Wykonałem sporo pracy z relacyjnymi bazami danych i myślę, że całkiem dobrze rozumiem podstawowe koncepcje dobrego projektowania schematów. Niedawno miałem za zadanie przejąć projekt, w którym DB zaprojektował wysoce opłacany konsultant. Daj mi znać, jeśli mój instynkt jelitowy - „WTF ??!?” - jest uzasadniony, czy ten facet jest tak genialny, że działa poza moim królestwem?
DB, o której mowa, to wewnętrzna aplikacja służąca do wprowadzania żądań od pracowników. Wystarczy spojrzeć na jego niewielką część, aby uzyskać informacje o użytkownikach i informacje o złożonym żądaniu. Zaprojektowałbym to tak:
Tabela użytkowników:
UserID (primary Key, indexed, no dupes)
FirstName
LastName
Department
Tabela zapytań
RequestID (primary Key, indexed, no dupes)
<...> various data fields containing request details
UserID -- foreign key associated with User table
Proste, prawda?
Konsultant zaprojektował to tak (z przykładowymi danymi):
UsersTable
UserID FirstName LastName
234 John Doe
516 Jane Doe
123 Foo Bar
DepartmentsTable
DepartmentID Name
1 Sales
2 HR
3 IT
UserDepartmentTable
UserDepartmentID UserID Department
1 234 2
2 516 2
3 123 1
RequestTable
RequestID UserID <...>
1 516 blah
2 516 blah
3 234 blah
Cała baza danych jest zbudowana w ten sposób, a każdy kawałek danych jest zamknięty w swojej własnej tabeli, z numerycznymi identyfikatorami łączącymi wszystko razem. Najwyraźniej konsultant czytał o OLAP i chciał „szybkości wyszukiwania liczb całkowitych”
Ma również dużą liczbę procedur przechowywanych, aby odwołać się do wszystkich tych tabel.
Czy jest to poprawny projekt dla małej lub średniej bazy danych SQL?
Dzięki za komentarze / odpowiedzi ...
Odpowiedzi:
Ma to dla mnie sens. Jest po prostu bardzo znormalizowany, co zapewnia dużą elastyczność, której inaczej byś nie miał. Dane zdenormalizowane to ból w tyłku.
źródło
Nie sądzę, że albo WTF jest uzasadnione, albo że facet robi jakiś szalony genialny projekt - to dość standardowa normalizacja bazy danych.
Powodem dla tabeli działów jest to, że jeśli nie umieścisz działów w osobnej tabeli, będziesz musiał kontaktować się z użytkownikami w działach „Sprzedaż”, „Sprzedaż”, „Sprzedawcy”, „Żagle” i „Sprzedaż”, chyba że zrobisz coś, aby temu zapobiec. A posiadanie dodatkowego stołu to (część) najlepszy sposób, jaki wiem, aby to zrobić.
To, czy powinna istnieć tabela UserDepartment, jest trudniejsze, co oczywiście oznacza, że żadna decyzja nie jest szalona. Z jednej strony jest to ból, gdy cały projekt stołu i logika zakładają jeden dział na użytkownika, a potem to się zmienia, z drugiej strony wykonywanie dodatkowego łączenia bez powodu przez lata i lata jest realną możliwością, a także bólem.
Osobiście zgodziłbym się z tobą, że tabela UserDepartment prawdopodobnie przesadza. Nawet jeśli jest uwzględnione, są szanse, że z czasem ludzie będą pisać zapytania, które zakładają, że jest tylko jeden użytkownik na dział, więc skończysz z najgorszym z obu światów - dodatkowe połączenie bez żadnego powodu przed potrzebowaniem stołu, i kod i tak nie działa, gdy dozwolony jest więcej niż jeden dział na użytkownika.
EDYCJA - Kluczowym czynnikiem decydującym o tym, czy należy wspierać relację wielu do wielu, jest to, czy reguły biznesowe są jasne. Jeśli nie masz pojęcia, jak mógłby działać użytkownik w wielu działach, dodanie tabeli nie ma sensu, ponieważ Twój kod nie jest w stanie poprawnie obsłużyć przypadków, w których użytkownik jest w wielu działach.
Wyobraź sobie, że na wszelki wypadek zezwoliłeś na wiele działów na użytkownika. Następnie zaimplementowano regułę biznesową do przypisywania prowizji na podstawie działu. Następnie dozwolonych było wiele działów. Na szczęście miałeś również zdolność przewidywania, aby napisać kod prowizji w sposób uwzględniający to. Niestety, dodałeś prowizje z każdego działu dla użytkowników w obu. Kierownictwo chciało, abyś oparł się na roli osoby przy każdej sprzedaży. Więc ile dobrego było z wyprzedzeniem przy stole? Co z innymi stolikami, które miałeś „na wszelki wypadek”, które w ogóle nigdy nie są potrzebne?
PÓŹNA EDYCJA - Innym powodem, dla którego konsultant mógł chcieć dodać wszystkie tabele pośredniczące, jest odpowiedź na to pytanie uzupełniające , na które odpowiedzi podaje kilka powodów, dla których refaktoryzacja bazy danych jest zwykle trudniejsza niż kod refaktoryzacji, co skłoniłoby cię do podejście „wstaw wszystkie tabele, których możesz potrzebować”.
źródło
Jeśli wymaga się posiadania wielu działów na użytkownika, ten projekt ma sens. Jedyną przeszkodą jest
UserDepartmentTable
posiadanie klucza zastępczego,UserDepartmentID
który nie jest potrzebny (po prostu utwórz klucz złożonyUserId
iDepartmentId
złożony).Jeśli użytkownik należy tylko do jednego działu, Twój projekt ma sens (choć tabela przeglądów działów nadal byłaby dobra).
źródło
Niektóre wymagania nie są jasne w twoim pytaniu. Prawidłowa odpowiedź zależy od tego, czego chce twój klient - gdybym był tobą, zapytałbym klienta o to:
0-Jaka jest różnica między użytkownikiem a pracownikiem?
1-Zakładając, że pracownik = użytkownik, co jeśli pracownik zmieni działy?
2-Czy grupa pracowników może złożyć 1 wniosek?
3-Czy pracownik może należeć do więcej niż jednego działu? Co z CEO
4-Czy jest podzbiór pracowników, którzy mogą składać wnioski?
5-Co stanie się z żądaniem, gdy rekord pracownika zostanie usunięty (jeśli w ogóle)?
6-Czy możesz usunąć prośbę? Co dzieje się po usunięciu żądania (upewnij się, że nie usuwasz rekordu pracownika przez RI)
7-Czy pracownik może złożyć „to samo” żądanie więcej niż jeden raz (zdefiniować „to samo”)
8-Jak obsługiwać wnioski o odejście pracowników z firmy (anulować lub usunąć prośby?)
Może być więcej pytań, ale moim zdaniem rozwiązanie zależy od dokładnych wymagań i zakresu projektu. Po ustaleniu schemat można uzyskać bezpośrednio. W związku z tym oba przedstawione rozwiązania mogą być poprawne.
źródło
Chciałbym dodać kilka uwag do formularza, które wyraźnie mówią o niektórych potencjalnych zaletach korzystania ze stołu do łączenia w sposób, w jaki zrobił to twój wysoko opłacany konsultant.
UserDepartmentTable.Department
nie jest „trudniejsze” niż wyszukiwanie jakiejkolwiek innej kolumny wUser
tabeli.UserDepartmentTable.Active
fałsz” i tworzy nowe aktywne powiązanie). Możliwe jest również wersjonowanie powiązań departamentów z modelem z dwoma tabelami (tylko użytkownik i dział), ale jest to trudniejsze i wymaga dodania co najmniej jednej kolumny lub wykonania akrobatyki bazy danych, aby uniknąć duplikowania kluczy podstawowych.Biorąc to pod uwagę, istnieje kilka powodów, aby NIE robić tego, co zrobił twój wysoko opłacany konsultant.
źródło
Bez pełnej struktury potrzebnych informacji nie mogę powiedzieć, czy to okropne, czy nie. Ale przynajmniej pokazany kawałek nie jest w stylu „WTF”. Wydaje się, że jest to trzecia normalna forma struktury danych (teoretycznie mamy też czwartą i piątą również)
Niektóre rozmowy mogą zawierać miejsce dla UserDepartmentTable między dwiema szkołami „naturalnych” i „sztucznych” kluczy w pokazanym fragmencie. Nic więcej, jak widzę
Normalizacja jest zasadą dobrego dewelopera / projektanta DB z wielu powodów, * normalizacje * de * są czasem stosowane w trakcie rozwoju głównie w celu szybkiego wygrania
źródło