2008-10-27 18 views
6

W prototypie bazy danych mam zestaw pól (takich jak nazwa, opis, status), które są wymagane w wielu różnych tabelach funkcjonalnie.Te same pola w większości tabel

Te pola mają zawsze taką samą funkcję użytkownika końcowego do etykietowania, wyświetlania, wyszukiwania, filtrowania itd. Nie są one częścią ograniczenia klucza obcego. Jak powinno to być modelowane?

mogę myśleć o następujących wariantach:

  • Każda tabela pobiera wszystkie te atrybuty. W takim przypadku, jak byś je nazwał? To samo, w każdej tabeli, albo z nazwą tabeli prefiksu (jak usrName, ProdName)

  • przenieść je do tabeli atrybutów dodać klucz obcy do „rdzenia” Stoły, przedstawieniu Attributes.PK

  • Jak wyżej, ale zamiast klucza obcego, użyj Atrybutu.PK jako PK w odpowiedniej tabeli rdzeniowej.

+0

To pytanie spowodowało, że zastanawiałem się, czy istnieje coś takiego jak koncepcja dziedziczenia w projektowaniu baz danych. Widzę, gdzie byłoby użyteczne, aby jedna tabela "dziedziczyła" kolumny i/lub ograniczenia z innej tabeli automatycznie. – MusiGenesis

+0

Przez "projekt bazy danych" rozumiem inżynierię silnika baz danych, a nie projektowanie bazy danych Northwinds. – MusiGenesis

+0

Istnieją takie rzeczy jak OODBMS (Object Oriented Databases), które są całkowicie różne od standardowych RDBMS, które mają wiele operacji typu OO, takich jak dziedziczenie – Mark

Odpowiedz

8

Wygląda na to, że możesz trochę pogodzić się z normalizacją. pamiętaj, to jest pomysł, że redukujesz nadmiarowość w swoich danych. Twój przykład wydaje się wskazywać, że martwisz się "nadmiarowością" w metadanych projektu bazy danych.

ostatecznie jednak user.name i user.description funkcjonalność są różne od product.name i product.description i powinny być traktowane jako takie. dla status, to zależy od tego, co przez to rozumiesz. jest status tylko wskaźnikiem aktywności produktu/użytkownika, czy jest aktywny? jeśli tak, to sensowne byłoby podzielenie tego na inną tabelę.

używając podanych informacji, jeśli „aktywny/expired/usunięte” jest jedynie wskazanie stanu w bazie danych, a następnie Zdecydowanie zgadza się ze strukturą tabeli tak:

users   products   status 
    id    id    id 
    name    name    name 
    description  description 
    status_id  status_id 

jednak jeśli status mogłyby być ewentualnie zmieniona reprezentować coś innego semantycznie (czyli dla użytkowników, być może „aktywny/emeryt/zwolniony”, którą proponujemy podział, że do przyszłego dowodu wzorem:

user_status  product_status 
    id    id 
    name   name 

w skrócie, normalizacji Twoje dane, a nie desi bazy danych gn.

+0

Nie martwię się, tylko się zastanawiam - dzięki ludziom :) – peterchen

1

Normalizacja jest często najlepszą praktyką w dowolnej relacyjnej bazie danych (w granicach rozsądku).

Jeśli masz pola takie jak stan (oznaczające stan w danym kraju), to tabela odniesienia, taka jak "Stan" z (id, short_name, long_name itp.) Może być drogą, którą należy przejść, a następnie każdy zapis odniesienia stan wymaga tylko kolumna state_id, która, jak już wspomniano, jest odniesienie do rekordu w tabeli państwa.

Jednak w niektórych przypadkach normalizacja wszystkich danych niekoniecznie jest wymagana, ponieważ po prostu komplikuje sprawy, ale powinno być oczywiste, gdzie to zrobić i gdzie tego nie robić.

Mam nadzieję, że to pomoże.

+0

"stan" oznaczało status (np. Aktywny/usunięty/wygasł, do historia utworów) - przepraszam za zamieszanie – peterchen

+0

Rozumiem, myślę, że obowiązują te same zasady, jeśli wiele tabel będzie korzystało z tych samych danych, to tabela odniesienia jest nadal drogą do zrobienia. Pozwala to również uniknąć błędów w pisowni, ponieważ odwołania do innych tabel są jedynymi miejscami, więc jedynym błędem może być pojedynczy wiersz w tabeli referencyjnej. – Mark

3

Jeśli nie używasz tej samej nazwy lub opisu, wartości w tabelach, nie powinieneś normalizować tych danych. Typy statusu są zwykle ponownie wykorzystywane, więc normalizuj je. Na przykład:

order_status_types 
- id 
- name 
- description 

shipping_accounts 
- id 
- name 
- description 

orders 
- order_status_type_id 
- shipping_account_id 

preferences 
- shipping_account_id 
1

Chciałbym nadać każdej tabeli własny zestaw kolumn, nawet jeśli mają one te same nazwy i są logicznie podobne.

Jeśli kiedykolwiek zajdzie potrzeba zmiany jednej z tabel, dodając lub usuwając niektóre z tych kolumn lub zmieniając ich typ danych, można to zrobić tylko w tabeli, w której się ona znajduje, zamiast zastanawiać się, jak skomplikować tabela atrybutów współdzielonych.

Podanie każdej kontroli tabeli dla jej własnych atrybutów promuje Cohesion, co jest dobrą rzeczą. Pozwala to również uniknąć pytania o kierunek, w którym poruszają się klucze obce.

W przypadku nazewnictwa kolumn nie jest konieczne ani zalecane umieszczanie prefiksów na nazwach kolumn. Jeśli kiedykolwiek dokonasz sprzężenia, w wyniku którego kolumny o tej samej nazwie będą pochodzić z dwóch tabel, użyj aliasów, aby je rozróżnić.

1

Zawsze podawałem każdej tabeli 3-literowy kod, który następnie używam we wszystkich nazwach pól. W ten sposób w tabeli produktów mam prdname, prddescription, prdstatus, aw pliku dostawcy mam nazwę-venname, vendescription, venstatus. Kiedy rzeczy się łączą, nie ma potrzeby martwić się o te same pola nazwane.

Oczywiście wszystkie tabele mają pole o nazwie zwykły stary id, a tabela produktów będzie miała pole o nazwie venid, które odnosi się do pola identyfikatora w tabeli dostawcy. W tym przypadku nie umieszczam na nim prefiksu prd, ponieważ żywioł ma sens i jest jednoznaczny.