Co jest bardziej wydajne: wiele tabel MySQL czy jedna duża tabela?

Przechowuję różne dane użytkownika w bazie danych MySQL. Pierwotnie został on skonfigurowany w różnych tabelach, co oznacza, że dane są połączone z identyfikatorami użytkownika i wyprowadzane za pomocą czasami skomplikowanych wywołań w celu wyświetlania i manipulowania danymi w razie potrzeby. Tworząc nowy system, prawie sensowne jest połączenie wszystkich tych tabel w jedną dużą tabelę powiązanych treści.

    Czy to będzie pomoc czy przeszkoda? [[3]}względy prędkości w wywołaniu, aktualizacji lub szukanie/manipulowanie?

Oto przykład mojej struktury tabeli:

  • użytkownicy-UserId, nazwa użytkownika, e-mail, zaszyfrowane hasło, data rejestracji, ip
  • user_details-dane cookie, nazwa, adres, dane kontaktowe, przynależność, dane demograficzne
  • user_activity-wkłady, Ostatnio online, Ostatnio oglądane
  • user_settings-ustawienia wyświetlania profilu
  • user_interests-zmienne targetable reklamy
  • user_levels-access prawa
  • user_stats-hity, talie

Edit: do tej pory podałem wszystkie odpowiedzi, wszystkie mają elementy, które zasadniczo odpowiadają na moje pytanie.

Większość tabel ma relację 1: 1, która była głównym powodem ich denormalizacji.

CZY pojawią się problemy, jeśli tabela obejmuje ponad 100 kolumn, gdy duża część tych komórek prawdopodobnie pozostanie pusta?

Author: Christopher Rapcewicz, 2009-07-14

8 answers

Wiele tabel pomaga w następujący sposób / przypadkach:

(a) jeśli różne osoby będą tworzyć aplikacje zawierające różne tabele, warto je podzielić.

(b) Jeśli chcesz dać różne rodzaje organów różnym osobom dla różnych części gromadzenia danych, może być wygodniej podzielić je. (Oczywiście można spojrzeć na odpowiednie definiowanie widoków i udzielanie na nich autoryzacji).

(c) do przenoszenia danych na różne miejsca, szczególnie w trakcie tworzenia, może mieć sens używanie tabel, które skutkują mniejszymi rozmiarami plików.

(d) mniejszy nadruk stóp może zapewnić komfort podczas tworzenia aplikacji na określonym zbiorze danych jednego podmiotu.

(e) jest taka możliwość: to, co uważałeś za pojedynczą wartość, może w przyszłości okazać się naprawdę wieloma wartościami. np. limit kredytowy jest obecnie pojedynczym polem wartości. Ale jutro możesz zdecydować się na zmianę wartości jako (data od, Data do, kredyt wartość). Stoliki podzielone mogą się teraz przydać.

Mój głos byłby za wieloma tabelami - z odpowiednio podzielonymi danymi.

Powodzenia.

 50
Author: user115905,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-14 12:46:33

Łączenie tabel nazywa się denormalizacją.

Może (lub nie) pomóc sprawić, aby niektóre zapytania (które sprawiają, że wiele JOINs) działały szybciej kosztem stworzenia piekła konserwacji.

MySQL może używać tylko metody JOIN, czyli NESTED LOOPS.

Oznacza to, że dla każdego rekordu w tabeli driving, MySQL lokalizuje pasujący rekord w tabeli driving w pętli.

Zlokalizowanie rekordu jest dość kosztowną operacją, która może trwać kilkadziesiąt razy dłużej niż czyste skanowanie rekordów.

Przeniesienie wszystkich rekordów do jednej tabeli pomoże Ci pozbyć się tej operacji, ale sama tabela staje się większa, a skanowanie tabeli trwa dłużej.

Jeśli masz wiele rekordów w innych tabelach, to zwiększenie skanowania tabeli może spowodować nadwagę korzyści z rekordów skanowanych sekwencyjnie.

/ Align = "left" /
 31
Author: Quassnoi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-14 12:28:36

Czy wszystkie są związkami 1:1? Chodzi mi o to, że jeśli użytkownik może należeć do, powiedzmy, różnych poziomów użytkowników lub jeśli zainteresowania użytkowników są reprezentowane jako kilka rekordów w tabeli zainteresowań użytkowników, natychmiast nie wchodzi w grę łączenie tych tabel.

Jeśli chodzi o poprzednie odpowiedzi na temat normalizacji, należy powiedzieć, że reguły normalizacji bazy danych całkowicie pominęły wydajność i przyglądają się tylko temu, co jest schludnym projektem bazy danych. To jest często to, co Ty chcesz osiągnąć, ale są chwile, w których sensowne jest aktywne denormalizowanie w dążeniu do wydajności.

Podsumowując, pytanie sprowadza się do tego, ile pól znajduje się w tabelach i jak często są one dostępne. Jeśli aktywność użytkownika często nie jest zbyt interesująca, może to być po prostu uciążliwe, aby zawsze mieć ją na tym samym rekordzie, ze względu na wydajność i ze względów konserwacyjnych. Jeśli niektóre dane, jak ustawienia, są dostępne bardzo często, ale po prostu zawiera zbyt wiele pola, może też nie być wygodne łączenie tabel. Jeśli zależy Ci tylko na wzroście wydajności, możesz rozważyć inne metody, takie jak oddzielenie ustawień, ale zapisanie ich w zmiennej sesji, dzięki czemu nie musisz często pytać o nie bazy danych.

 16
Author: David Hedlund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-14 12:27:59

Czy Wszystkie z tych tabel mają 1-to-1 związek? Na przykład, czy każdy wiersz użytkownika będzie miał tylko jeden odpowiadający mu wiersz w user_stats lub user_levels? Jeśli tak, to może mieć sens połączenie ich w jedną tabelę. Jeśli związek nie jest 1 to 1 chociaż prawdopodobnie nie miałoby sensu łączenie ich (denormalizacja).

Mając je w oddzielnych tabelach vs. jeden stół prawdopodobnie będzie miał niewielki wpływ na wydajność choć chyba że masz setki tysięcy lub miliony rekordy użytkowników. Jedynym prawdziwym zyskiem, który otrzymasz, jest uproszczenie zapytań poprzez ich połączenie.

ETA:

Jeśli Twoja troska dotyczy zbyt dużej liczby kolumn , pomyśl o Jakie rzeczy zwykle używasz razem i połącz je , pozostawiając resztę w osobnej tabeli (lub kilku osobnych tabel, jeśli zajdzie taka potrzeba).

Jeśli spojrzysz na sposób, w jaki używasz danych, domyślam się, że odkryjesz, że coś w rodzaju 80% zapytań używa 20% tych danych pozostałe 80% danych jest wykorzystywane tylko sporadycznie. Połącz to często używane 20% W jeden stół, i zostaw 80%, które nie są często używane w oddzielnych tabelach, a prawdopodobnie będziesz miał dobry kompromis.

 10
Author: Eric Petroelje,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-20 12:06:56

Dlaczego nie użyć tego samego podejścia WordPress robi, mając tabelę użytkowników z podstawowymi informacjami o użytkownikach, które każdy ma, a następnie dodając tabelę "user_meta", która może być w zasadzie dowolną parą kluczy, wartości powiązaną z identyfikatorem użytkownika. Więc jeśli chcesz znaleźć wszystkie meta informacje dla użytkownika, możesz po prostu dodać to do zapytania. Nie zawsze będziesz musiał dodawać dodatkowe zapytanie, jeśli nie jest to potrzebne do takich rzeczy, jak logowanie. Korzyści płynące z tego podejścia pozostawia również stół otwarty na dodawanie nowych funkcje dla użytkowników, takie jak przechowywanie ich uchwyt twitter lub każdego indywidualnego zainteresowania. Nie będziesz też musiał radzić sobie z labiryntem powiązanych identyfikatorów, ponieważ masz jedną tabelę, która reguluje wszystkie metadane i ograniczysz ją do tylko jednego skojarzenia zamiast 50.

Wordpress robi to specjalnie, aby umożliwić dodawanie funkcji za pomocą wtyczek, dzięki czemu Twój projekt będzie bardziej skalowalny i nie będzie wymagał całkowitego remontu bazy danych, jeśli chcesz dodać nową funkcję.

 7
Author: Rudy Garcia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-07 14:46:50

Tworzenie jednej masywnej tabeli jest sprzeczne z zasadami relacyjnej bazy danych. Nie połączyłbym ich wszystkich w jeden stół. Masz zamiar uzyskać wiele instancji powtarzających się danych. Jeśli na przykład twój użytkownik ma trzy zainteresowania, będziesz miał 3 Wiersze z tymi samymi danymi użytkownika, aby zapisać trzy różne zainteresowania. Definitywnie przejdź do podejścia wielu "znormalizowanych" tabeli. Zobacz to strona Wiki dla normalizacji bazy danych.

Edit: Zaktualizowałem swoją odpowiedź, tak jak ty zaktualizowałem twoje pytanie... Zgadzam się z moją początkową odpowiedzią jeszcze bardziej teraz...

Duża część tych komórek to prawdopodobnie pozostanie pusty

Jeśli na przykład użytkownik nie miał żadnych zainteresowań, jeśli normalizujesz, to po prostu nie będziesz miał wiersza w tabeli zainteresowań dla tego użytkownika. Jeśli masz wszystko w jednej ogromnej tabeli, będziesz miał kolumny (i najwyraźniej wiele z nich), które zawierają tylko NULL.

Pracowałem w firmie telefonicznej, gdzie było mnóstwo tabel, uzyskanie danych może wymagać wielu złączeń. Gdy wydajność odczytu z tych tabel była krytyczna, wtedy procedury, w których utworzono, które mogłyby generować płaską tabelę (tj. tabelę denormalizowaną), która nie wymagałaby połączeń, obliczeń itp., na które raporty mogłyby wskazywać. Są one następnie używane w połączeniu z agentem SQL server do uruchamiania zadania w określonych odstępach czasu(tj. tygodniowy widok niektórych statystyk byłby uruchamiany raz w tygodniu i tak dalej).

 6
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-14 12:45:09

Myślę, że to jedna z tych sytuacji "to zależy". Posiadanie wielu tabel jest czystsze i prawdopodobnie teoretycznie lepsze. Ale kiedy musisz dołączyć 6-7 tabel, aby uzyskać informacje o jednym użytkowniku, możesz zacząć przemyśleć to podejście.

 3
Author: Tundey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-14 12:24:21

Powiedziałbym, że to zależy od tego, co naprawdę oznaczają Pozostałe tabele. Czy user_details zawiera więcej niż 1 więcej / userów i tak dalej. To, jaki poziom normalizacji najlepiej odpowiada twoim potrzebom, zależy od twoich wymagań.

Jeśli masz jedną tabelę z dobrym indeksem, która prawdopodobnie byłaby szybsza. Ale z drugiej strony prawdopodobnie trudniejsze do utrzymania.

Dla mnie wygląda na to, że można pominąć User_Details, ponieważ prawdopodobnie jest to relacja 1 do 1 z użytkownikami. Ale reszta to chyba dużo wiersze na użytkownika?

 1
Author: Richard L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-14 12:27:18