Czy jest to dobry sposób na modelowanie informacji adresowych w relacyjnej bazie danych?

Zastanawiam się, czy to dobry projekt. Mam kilka tabel, które wymagają danych adresowych (np. Ulica, Kod Pocztowy/zip, kraj, faks, e-mail). Czasami ten sam adres będzie powtarzany wiele razy. Na przykład adres może być przechowywany przeciwko dostawcy, a następnie na każdym zamówieniu wysłanym do niego. Dostawca może następnie zmienić swój adres, a każde kolejne zamówienie zakupu powinno mieć nowy adres. To bardziej skomplikowane niż to, ale to przykładowe wymagania.

Opcja 1 Umieść wszystkie kolumny adresu jako atrybuty na różnych tabelach. Skopiuj szczegóły z dostawcy do PO w trakcie jego tworzenia. Potencjalnie przechowywać wiele kopii

Opcja 2 Utwórz oddzielną tabelę adresów. Mieć klucz obcy z tabeli dostawcy i zamówienia zakupu do tabeli adresowej. Zezwalaj tylko na wstawianie i usuwanie w tabeli adresów, ponieważ aktualizacje mogą zmienić więcej niż zamierzasz. Wtedy miałbym jakieś zaplanowane zadanie, które usuwa wszystkie wiersze z tabeli adresów, do których nie odwołuje się nic, więc nieużywane wiersze nie zostały pozostawione. Być może mają również unikalne ograniczenie dla wszystkich kolumn nie-pk w tabeli adresów, aby zatrzymać duplikaty, jak również.

Skłaniam się ku opcji 2. Jest lepszy sposób?

EDIT: muszę zachować adres na zamówieniu, jak to było w momencie wysłania. Ponadto, jest to nieco bardziej skomplikowane, że zasugerowałem, ponieważ może być adres dostawy i adres rozliczeniowy (nie ma również kilka innych tabel, które mają informacje adresowe).

Po jakimś czasie usunę stare zamówienia masowo na podstawie ich daty. To jest po tym, że zamierzałem zbierać śmieci wszelkie rekordy adresów, które nie są już odwołane przez nic (w przeciwnym razie czuję, jakbym tworzy przeciek).

Author: WW., 2008-11-20

7 answers

Używam tego jako jednego z moich pytań. Poniżej znajduje się dobry początek:

Addresses
---------
AddressId (PK)
Street1
... (etc)

I

AddressTypes
------------
AddressTypeId
AddressTypeName

I

UserAddresses (substitute "Company", "Account", whatever for Users)
-------------
UserId
AddressTypeId
AddressId

W ten sposób Twoje adresy są całkowicie nieświadome tego, w jaki sposób są używane, a twoje podmioty (użytkownicy, konta) również nie wiedzą bezpośrednio nic o adresach. Wszystko zależy od tabel łączących, które tworzysz (w tym przypadku adresy użytkownika, ale możesz zrobić to, co pasuje do twojego modelu).

Jedna z nieco sprzecznych rad dla potencjalnie dużej bazy danych: śmiało, umieść adres "podstawowy" bezpośrednio na swoich obiektach (w tym przypadku w tabeli użytkowników) wraz z polem "HasMoreAddresses". Wydaje się to nieciekawe w porównaniu do używania czystego projektu powyżej, ale może uprościć kodowanie dla typowych przypadków użycia, a denormalizacja może mieć duże znaczenie dla wydajności.
 27
Author: Eric Z Beard,
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
2008-11-20 22:28:21

Opcja 2, bez wątpienia.

Ważne rzeczy, o których należy pamiętać: ważnym aspektem projektowania jest wskazanie użytkownikom, kiedy adresy są ze sobą połączone. Adres firmowy jest taki sam jak adres wysyłki; jeśli chcą zmienić adres wysyłki, czy chcą zmienić również adres firmowy, czy chcą określić nowy dok załadunkowy? Tego typu rzeczy, a możliwość prezentowania użytkownikom tych informacji i zmiany rzeczy za pomocą tego rodzaj ziarnistości jest bardzo ważny. Jest to również ważne, jeśli chodzi o aktualizacje; daj użytkownikowi szczegółowość" podziel " wpisy. Nie, że ten rodzaj interfejsu użytkownika jest łatwy do zaprojektowania; w rzeczywistości jest to suka. Ale to naprawdę ważne, aby to zrobić; cokolwiek mniej spowoduje prawie na pewno, że użytkownicy będą bardzo sfrustrowani i zirytowani.

Również; zdecydowanie zalecam trzymanie starych danych adresowych; nie uruchamiaj procesu, aby go wyczyścić. Jeśli nie masz bardzo ruchliwej bazy danych, twoja baza danych oprogramowanie będzie w stanie obsłużyć nadmiar danych. Naprawdę. Jednym z częstych błędów widzę o bazach danych jest próba overoptimize; chcesz zoptymalizować piekło z zapytań, ale nie chcesz, aby zoptymalizować swoje niewykorzystane DANE się. (Ponownie, jeśli aktywność bazy danych jest bardzo wysoka, może być konieczne, aby coś to robi, ale to prawie pewność, że baza danych będzie działać dobrze z nadal nadmiar danych wokół w tabelach.) W większości sytuacji jest to faktycznie korzystniejsze aby po prostu pozwolić swojej bazie danych rosnąć niż jest próba jej optymalizacji. (Usunięcie sporadycznych danych z tabel nie spowoduje znaczącego zmniejszenia rozmiaru bazy danych, a kiedy to nastąpi... renifery, które to powoduje, mogą być gigantycznym drenażem w bazie danych.)

 6
Author: Paul Sonier,
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
2008-11-20 22:28:57

Chyba zgadzam się z JohnFx..

Kolejna rzecz o (ślimak -) adresach pocztowych, ponieważ chcesz dołączyć kraj zakładam, że chcesz wysyłać / wysyłać pocztę międzynarodową, proszę zachować pole adresu głównie dowolny tekst. To naprawdę irytujące, że trzeba wymyślić 5-cyfrowy Kod pocztowy, gdy Norwegia nie ma kodów pocztowych, mamy 4-cyfrowe numery pocztowe.

Najlepsze pola to:

  • Nazwa / Firma
  • Address (multiline textarea)
  • kraj

To powinien być dość globalny, jeśli system pocztowy USA wymaga kodów pocztowych w określonym formacie, to Dołącz to zbyt, ale uczynić go opcjonalnym, chyba że USA jest wybrany jako kraj. Każdy wie, jak sformatować adres w swoim kraju, tak długo, jak zachować linebreaks powinno być w porządku...

 2
Author: Stein G. Strindhaug,
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
2008-11-20 22:28:22

Czy chcesz zachować historyczny zapis, jaki adres był pierwotnie na zamówieniu?

Jeśli tak, przejdź do opcji 1, w przeciwnym razie zapisz ją w tabeli dostawcy i połącz każde zamówienie zakupu z dostawcą.

BTW: pewną oznaką słabego projektu DB jest potrzeba zautomatyzowanego zadania, aby utrzymać dane "wyczyszczone" lub w synchronizacji. Wariant 2 jest prawdopodobnie złym pomysłem w tym zakresie

 1
Author: JohnFx,
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
2008-11-20 22:11:57

Dlaczego któryś z wierszy w tabeli adresów stałby się Nieużywany? Z pewnością nadal będą wskazywane przez zlecenie zakupu, które ich używało?

Wydaje mi się, że zatrzymanie duplikatów powinno być priorytetem, negując w ten sposób potrzebę czyszczenia.

 1
Author: cagcowboy,
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
2008-11-20 22:27:48

W przypadku zamówień, nigdy nie chcesz aktualizować adresu, ponieważ adres osoby (lub firmy) zmienił się, jeśli zamówienie zostało wysłane. Sprawdziłeś, gdzie zamówienie zostało wysłane, jeśli wystąpił problem z zamówieniem.

Tabela adresów to dobry pomysł. Utwórz na nim unikalne ograniczenie, aby ten sam obiekt nie mógł mieć zduplikowanych adresów. Możesz je nadal uzyskać, ponieważ użytkownicy mogą dodać kolejny zamiast szukać ich i jeśli pisownia rzeczy nieco inaczej (St. zamiast ulicy) unikalne ograniczenie nie zapobiegnie temu. Skopiuj dane w momencie tworzenia zamówienia do zamówienia. Jest to jeden przypadek, w którym chcesz wiele rekordów, ponieważ potrzebujesz historycznego zapisu tego, co wysłałeś gdzie. Tylko umożliwienie wstawiania i usuwania do tabeli nie ma dla mnie sensu, ponieważ nie są one bezpieczniejsze niż aktualizacje i wymagają więcej pracy dla bazy danych. Aktualizacja odbywa się jednym wywołaniem do bazy danych. Jeśli adres zmieni się w Twoim pomyśle, musisz najpierw usunąć stary adres, a następnie wstaw nowy. Nie tylko więcej wywołań do bazy danych, ale Dwukrotna szansa popełnienia błędu w kodzie.

 0
Author: HLGEM,
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
2008-11-20 22:29:02

Widziałem, że każdy system korzystający z opcji 1 ma problemy z jakością danych. Po 5 latach 30% wszystkich adresów nie będzie już aktualne.

 0
Author: Stephan Eggermont,
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-02-03 18:24:14