2011-10-26 26 views
20

Czy należy zaimplementować normalizację odczytanej bazy danych (używając tabel łączenia), czy też powinienem użyć typu ENUM dla danych statycznych lub dynamicznych?Normalizacja bazy danych MySQL

Na przykład:

Mam tabeli USER z user_status. Czy powinienem utworzyć tabelę tabeli status lub utworzyć listę ENUM ze stanami?

Dzięki G

Odpowiedz

25

IMHO, rozszerzenie enum sprawia, że ​​znacznie łatwiej osadzić semantykę na stole, a także poprawia efektywność poprzez:

  1. zmniejszając liczbę sprzężeń wymagane dla zapytania
  2. zmniejszenie liczby otwartych tabel w DBMS

Jedyne wady Jestem świadomy jest

  1. E Typ NUM nie jest realizowany przez innych DBMS
  2. jeśli zdecydujesz się dodać dodatkowe wartości do zestawu ENUM w późniejszym terminie, Aplikujesz aktualizację DDL - co może zająć dużo czasu z bardzo dużym stole

HTH

C.

+1

Test wydajności: http://www.mysqlperformanceblog.com/2008/01/24/enum-fields-vs-varchar-vs-int-joined-table-what-is-faster/ –

+1

Istnieją inne problemy z 'ENUM '. Po pierwsze, wszystkie kolumny 'ENUM' mogą przyjmować specjalną" nieznaną "wartość pustego ciągu znaków (oprócz" NULL ", jeśli jest to dozwolone); co więcej, ta wartość będzie używana do przypisania nieprawidłowej wartości, chyba że używany jest tryb ścisły SQL. Może to doprowadzić do niezamierzonej niespójności bazy danych; również, jeśli faktycznie ma się jawnie pustą wartość ciągu na liście "ENUM", może to doprowadzić do ogromnego zamieszania (ponieważ należy sprawdzić wartość liczbową, aby określić, który "typ" pustego ciągu jest przechowywany). – eggyal

+1

Ponadto niejawna konwersja wartości liczbowych w kontekstach numerycznych może spowodować poważne zamieszanie - szczególnie, jeśli próbuje się użyć ciągów reprezentujących liczby jako wartości "ENUM". Instrukcja podaje dobry przykład listy 'ENUM'' ('0', '1', '2') ':" * Jeśli przechowujesz '2', jest interpretowany jako wartość indeksu i staje się' '1 "(wartość z indeksem 2) Jeśli przechowujesz' '2'', to dopasowuje wartość wyliczenia, więc jest zapisywane jako' '2''. Jeśli przechowujesz '' 3'', to nie pasuje do żadnej wartość wyliczeniowa, więc jest traktowana jako indeks i staje się "2" (wartość z indeksem 3). * " – eggyal

0

To zależy od architektury i wielu innych czynników.

Na przykład nie zezwala się na odczyt/zapis danych, z wyjątkiem korzystania z procedur przechowywanych. W tym przypadku możesz czuć się wolnym typem "tinyint". Jeśli zezwalasz na czytanie/pisanie z bezpośrednimi zapytaniami, lepiej jest użyć ograniczenia, tj. ENUM, aby uniknąć niewłaściwych statusów (jeśli interfejs użytkownika lub back-end może ustawić ten "zły" status oczywiście).

Z drugiej strony (i jest to możliwe) mogą wystąpić zmiany w przepływie danych i być może trzeba będzie dodać nowe stany. W tym przypadku będziesz potrzebować: 1) nic nie rób, jeśli masz statyczny typ danych; 2) zmień jeśli masz ENUM.

Więc ... moja odpowiedź brzmi: to zależy od zastosowania i wymagań.

+2

można wymusić poprawne statusy przez zagranicznych kluczowych ograniczeń, jak również (z wykorzystaniem tabel InnoDB.) – Inca

+0

... i stworzyć kolejną jedną tabelę. Uważam, że "nadmierna normalizacja" (posiadanie jednej dodatkowej tabeli dla każdego statusu) nie jest ogólnie dobrym podejściem. – ravnur

+0

Czy możesz wyjaśnić, dlaczego nie? Nie ma problemu z posiadaniem wielu tabel w ogóle. (I pozwalają na większą elastyczność, na przykład dodawanie edytowalnych opisów do stanu lub wyłączanie jednego dla nowych rekordów przy zachowaniu go dla starych rekordów.) – Inca

1

Innym rzeczy należy uznać za ...

enum może być aktualizowana tylko thru modyfikacji struktury bazy danych, gdzie indziej połączonej tabeli pozwala na dynamiczne tworzenie rekordu.