Najlepszy sposób na modelowanie singletonu w relacyjnej bazie danych


12

Podczas projektowania schematu relacyjnej bazy danych dla aplikacji internetowych często znajduję przypadek, w którym kończę tworzenie tabeli zawierającej tylko jeden wiersz i tylko jeden wiersz. Wydaje się, że jest to niewłaściwy sposób zaprojektowania go, ale nie mogę wymyślić niczego znacznie lepszego lub jest to oczywiście „właściwy sposób na zrobienie tego”.

Najnowszym przykładem jest witryna, która pozwala użytkownikom ręcznie kontrolować zawartość strony głównej. Jest tylko jedna strona główna. Utworzyłem tabelę zawierającą wszystkie pola niezbędne do zbudowania strony głównej, takie jak pole tekstowe dla obszaru zawierającego tekst opisowy. Pole do przechowywania nazwy dużego pliku obrazu. Niektóre klucze obce, które wskazują artykuły, które będą prezentowane na stronie głównej itp. Działa, ale źle jest mieć tabelę z jednym wierszem.

W przeszłości próbowałem wielu innych projektów, takich jak dopuszczanie wielu wierszy w tabeli strony głównej i wybieranie jednego losowo. Próbowałem dodać pole logiczne o nazwie „aktywne” i losowo wybrać jedną z aktywnych stron głównych. Próbowałem wymusić, aby tylko jeden wiersz był aktywny w danym momencie w logice aplikacji. Próbowałem nawet nie tworzyć tabeli strony głównej i mieć wszystkie inne elementy, takie jak artykuły, aby mieć pola boolowskie o nazwach takich jak featured_on_homepage.

W większości przypadków mogłem zbudować stronę główną z kilkoma stałymi w pliku ustawień. Główny problem z plikiem ustawień polega na tym, że znajduje się on pod kontrolą programisty. Ponieważ coś takiego jak treść strony głównej jest czymś do edycji przez użytkownika, musi przejść do bazy danych.

W wielu witrynach nie mam tego problemu, ponieważ mogę tworzyć takie rzeczy, jak strona główna za pomocą zapytania, na przykład wybierając pięć najnowszych artykułów. Ale kiedy mam strony ręcznie wyselekcjonowane według ścisłych wymagań, trudno jest modelować je w bazie danych. Ale wyobraź sobie, że masz stolik ze zdjęciami i stolik z artykułami. Wymagane jest, aby strona główna wyświetlała dokładnie pięć zdjęć, dokładnie trzy artykuły i dwa bloki dowolnego tekstu ręcznie kontrolowanego przez użytkownika. Jak we właściwy sposób modelować to w bazie danych?

Mam też ten problem z modelowaniem w wielu innych przypadkach oprócz samych stron głównych. To tylko najprostszy i najogólniej stosowany przykład, jaki mogłem wymyślić.


W ogóle nie jest jasne, jaki problem stanowi dla ciebie tabela z jednym rzędem, poza tym, że w jakiś sposób stanowi marnotrawstwo tabeli. Czy na pewno próbujesz rozwiązać problem, na który cierpisz?
David Aldridge

Odpowiedzi:


10

Jednym prostym podejściem byłoby zapisanie właściwości strony głównej w tabeli właściwości (lub nazwanie jej czymś innym), która składa się z kolumn Nazwa i Wartość.

HomePageProperty1 - UserValue1

HomePageProperty2 - UserValue2

To może nie być idealne rozwiązanie, ale jest proste i elastyczne. Eliminuje również tabelę w scenariuszu z jednym rzędem.


1
To podejście działa na wiele celów. Na przykład przechowuję informacje o wersji schematu, wskaźniki rotacji dla rzeczy, które należy cyklicznie codziennie itp. Informacje o wersji schematu są ważne podczas diagnozowania, co poszło nie tak. Jest to rozsądny sposób upewnienia się, że łatka została zastosowana do poprawki opartej tylko na bazie danych.
Berin Loritsch,

2
+1 - Dokładny układ tabeli, który dał mi nasz architekt danych w podobnym celu.
Ali

3
Problem z tym podejściem polega na tym, że musisz reprezentować różne typy zmiennych jako różne kolumny i mieć logikę, aby powiedzieć, której kolumny użyć, a które są obowiązkowe. Nie można zdefiniować, że wartość logiczna jest wartością logiczną lub że data jest datą, lub że określony atrybut nie może mieć wartości null lub musi mieścić się w określonym zakresie lub spełniać warunek - wszystkie rzeczy, które są banalnie proste z pojedynczym stołem.
David Aldridge

3

Nie jest dla mnie jasne, że masz problem, który musisz rozwiązać.

Tabela z jednym wierszem w żaden sposób nie stanowi problemu dla samej bazy danych i pozwala na stosowanie typów danych i ograniczeń do danych.

Szczerze mówiąc, nie jestem pewien, czy próbujesz rozwiązać prawdziwy problem.


2

Wydaje mi się, że używasz bazy danych do czegoś, co powinno faktycznie być przechowywane jako plik.

Twój opis przypomina mi wiele stron Wiki, na których użytkownicy mogą edytować treść. W Wiki lub przynajmniej w implementacjach, które widziałem, strony są utrwalane jako pliki.

Pomaga to w innych szczegółach internetowych, takich jak umożliwienie użytkownikom buforowania strony głównej, co jest praktycznie bezpłatne, jeśli przechowujesz strony jako pliki, ale będziesz musiał ręcznie wdrożyć logikę unieważnienia pamięci podręcznej, jeśli budujesz strona przy każdym żądaniu na podstawie treści przechowywanych w bazie danych.

W każdym razie chcę tylko wyjaśnić, że chociaż większość trwałych danych aplikacji jest przechowywana w bazie danych, nie oznacza to, że musimy tam wszystko przechowywać. Bazy danych są tylko jednym z narzędzi naszego handlu. Musimy nauczyć się korzystać z tak wielu różnych narzędzi, jak to możliwe.


2

W tabeli z jednym rzędem nie ma absolutnie nic złego.

Jeśli jest to część twojego projektu, powinieneś go egzekwować. Nadaj tabeli kolumnę tożsamości, nadaj jej ograniczenie unikatowości, a następnie dodaj ograniczenie kolumny, aby zezwolić tylko na jedną wartość. Zapewni to, że nikt nie będzie w stanie dodać drugiego wiersza, co może być katastrofalne, jeśli instrukcje SQL czytające tabelę (co zrozumiałe) nie zawierają klauzuli where.

Jeśli zaczniesz otrzymywać dużą liczbę kolumn, możesz ulec pokusie zawężenia tabeli i zamiast tego mieć jeden wiersz na element konfiguracji. To nie jest najlepszy pomysł, ponieważ tracisz bezpieczeństwo i sprawdzanie poprawności typu. Utraciłbyś także kompatybilność z multitenancy , co może być dla Ciebie ważne. Lepszym rozwiązaniem byłoby ponowne przemyślenie, jakie naprawdę są twoje jednostki i posiadanie osobnych tabel jednorzędowych dla różnych jednostek.

Tak, nie tylko mówię, że tabela z jednym wierszem jest OK, ale sugeruję, że możesz chcieć więcej niż jednego z nich.


1

Możesz utworzyć tabelę o nazwie STATIC_CONTENT i mieć kolumny dla klucza, a także zawartość, aktywne / nieaktywne moduły śledzące itp. Następnie utwórz wiersz z kluczem „Strona główna”, a na stronie głównej załaduj zawartość statyczną dla tego klucza i wyświetl to. W ten sposób, gdy masz inną statyczną treść (o stronie, stronie kontaktowej itp.), Możesz dodać wiersze do tej tabeli.


1

Nie ma w sobie nic złego w tabeli z tylko jednym rzędem. Jeśli kiedykolwiek masz tylko jedną instancję określonego bytu, może to być najbardziej naturalny sposób na przedstawienie tego.

Ale losowy wybór wiersza jest zły i zły. Jeśli logika domeny oczekuje tylko jednego wiersza, jest to oczywiście błąd w danych, jeśli w rzeczywistości jest ich więcej. Powinieneś więc dowiedzieć się, kto lub co zapisuje nieprawidłowe dane do bazy danych i uniemożliwić im to! W zależności od bazy danych można prawdopodobnie dodać ograniczenie do tabeli, aby zapobiec temu, np. Dopuszczając tylko określoną wartość jako klucz podstawowy.


0

Aby dodać do Waltera ..

Struktura tabeli właściwości powinna dopuszczać wiele typów danych.

Fileds:
PropertyName
PropertyTextValue
PropertyDateValue
PropertyNumericValue
PropertyBoolValue

W jaki sposób możesz zagwarantować, że w wierszu ustawiana jest tylko jedna wartość właściwości? Łatwo jest to wymusić w aplikacji, ale co, jeśli ktoś ręcznie zaktualizuje bazę danych i włoży do niej jakieś dane?
Apreche,

0

Wydaje mi się, że mógłbyś wyodrębnić jeszcze jeden poziom. Ostatecznie „strona główna” to „strona”. Możesz mieć różne typy stron o potrzebnych właściwościach. Jeśli masz sekcje w swojej witrynie, prawdopodobnie potrzebujesz „SectionHomePage”, która może równie dobrze działać tak samo jak „Strona główna”.

Wymagane jest, aby strona główna wyświetlała dokładnie pięć zdjęć, dokładnie trzy artykuły i dwa bloki dowolnego tekstu ręcznie kontrolowanego przez użytkownika. Jak we właściwy sposób modelować to w bazie danych?

Spróbujmy tak. Dodaję tabelę ArticlePage, abyś mógł zobaczyć, jak odpowiednio rozdzielić właściwości.

PAGES
Id
Title
Description

HOMEPAGES
PageId (FK)
PhotoListLimit
ArticleListLimit
TextBlockListLimit

ARTICLEPAGE
PageId (FK)
ArticleMainQuote
ArticleMainBody
ArticlePhoto1
ArticlePhoto2

To działałoby dla mnie dobrze, działałoby nawet świetnie dla dużej witryny.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.