Mysql
 sql >> Baza danych >  >> RDS >> Mysql

mysql:użyj SET czy wielu kolumn?

Wygląda na to, że interesuje Cię głównie wydajność.

Kilka osób zasugerowało podzielenie na 3 tabele (tabela kategorii plus prosta tabela odsyłaczy lub bardziej wyrafinowany sposób modelowania hierarchii drzewa, na przykład zestaw zagnieżdżony lub zmaterializowana ścieżka), co jest pierwszą rzeczą, o której pomyślałem, czytając twoje pytanie .

W przypadku indeksów takie w pełni znormalizowane podejście (dodające dwa sprzężenia) nadal będzie miało „całkiem dobrą” wydajność odczytu. Jednym z problemów jest to, że INSERT lub UPDATE do zdarzenia teraz może również zawierać jeden lub więcej INSERT/UPDATE/DELETE do tabeli odsyłaczy, co w MyISAM oznacza, że ​​tabela odsyłaczy jest zablokowana, a w InnoDB oznacza, że ​​wiersze są zablokowane. więc jeśli twoja baza danych jest zajęta znaczną liczbą zapisów, będziesz mieć większe problemy z rywalizacją, niż gdyby tylko wiersze zdarzeń były zablokowane.

Osobiście wypróbowałbym to w pełni znormalizowane podejście przed optymalizacją. Ale zakładam, że wiesz, co robisz, że twoje założenia są poprawne (kategorie nigdy się nie zmieniają) i masz wzorzec użycia (wiele zapisów), który wymaga mniej znormalizowanej, płaskiej struktury. To całkowicie w porządku i jest częścią tego, o co chodzi w NoSQL.

SET a „wiele kolumn”

Tak więc, jeśli chodzi o twoje pytanie "SET vs. wiele kolumn", mogę powiedzieć, że pracowałem z dwiema firmami z inteligentnymi inżynierami (którego produktami były aplikacje internetowe CRM ... jedna była właściwie zarządzaniem zdarzeniami) i obie zastosował podejście „wiele kolumn” dla tego rodzaju statycznych danych zestawu.

Radzę pomyśleć o wszystkich zapytaniach, które będziesz wykonywać w tej tabeli (ważonych według ich częstotliwości) oraz o tym, jak będą działały indeksy.

Po pierwsze, przy podejściu „wielu kolumn” będziesz potrzebować indeksów w każdej z tych kolumn, aby móc wykonać SELECT FROM events WHERE CategoryX = TRUE . Z indeksami jest to superszybkie zapytanie.

W przeciwieństwie do SET, musisz użyć bitowego AND (&), LIKE lub FIND_IN_SET(), aby wykonać to zapytanie. Oznacza to, że zapytanie nie może używać indeksu i musi przeprowadzić liniowe przeszukiwanie wszystkich wierszy (możesz użyć polecenia EXPLAIN, aby to sprawdzić). Powolne zapytanie!

To jest główny powód, dla którego SET to zły pomysł — jego indeks jest użyteczny tylko wtedy, gdy wybierasz według dokładnych grup kategorii. SET działa świetnie, jeśli wybierasz kategorie według wydarzenia, ale nie na odwrót.

Podstawowym problemem związanym z mniej znormalizowanym podejściem „wielu kolumn” (w porównaniu z w pełni znormalizowanym) jest to, że nie skaluje się. Jeśli masz 5 kategorii i nigdy się nie zmieniają, to dobrze, ale jeśli masz 500 i je zmieniasz, to duży problem. W twoim scenariuszu, przy około 30, które nigdy się nie zmieniają, głównym problemem jest to, że w każdej kolumnie znajduje się indeks, więc jeśli wykonujesz częste zapisy, te zapytania stają się wolniejsze z powodu liczby indeksów, które muszą zostać zaktualizowane. Jeśli wybierzesz to podejście, możesz sprawdzić dziennik powolnych zapytań MySQL, aby upewnić się, że nie występują odstające powolne zapytania z powodu rywalizacji w ruchliwych porach dnia.

W twoim przypadku, jeśli twoja aplikacja jest typową aplikacją internetową o dużym obciążeniu odczytu, myślę, że pójście z podejściem „wielu kolumn” (tak jak dwa produkty CRM z tego samego powodu) jest prawdopodobnie rozsądne. Jest zdecydowanie szybciej niż SET dla tego zapytania SELECT.

TL;DR Nie używaj SET, ponieważ zapytanie „wybierz zdarzenia według kategorii” będzie powolne.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dopasowywanie rekordów z dwóch tabel

  2. Czy należy unikać MEDIUMINT w MySQL?

  3. Jak wykonać kopię zapasową baz danych MySQL za pomocą AutoMySQLBackup

  4. Python od podstaw:stwórz dynamiczną stronę internetową

  5. LOAD DATA LOCAL INFILE wyświetla błąd Użyte polecenie nie jest dozwolone w tej wersji MySQL