Do domeny lub nie do domeny


15

Standardy SQL92 i SQL99 definiują konstrukcje DDL . Nie wszystkie bazy danych obsługują tę funkcję lub mają inną nazwę (na przykład SQL Server ma typy zdefiniowane przez użytkownika ).CREATE DOMAIN

Umożliwiają one zdefiniowanie ograniczonego typu danych, który będzie używany w ich bazie danych, w celu uproszczenia i egzekwowania reguł dotyczących dozwolonych wartości. Taki typ danych mógłby być wykorzystywany w deklaracjach kolumn, w danych wejściowych i wyjściowych procedur przechowywanych i funkcji itp.

Chciałbym wiedzieć:

  • Czy ludzie faktycznie używają domen w swoich projektach baz danych?
  • Jeśli tak, w jakim stopniu?
  • Jak są one użyteczne?
  • Jakie napotkaliście pułapki?

Próbuję ocenić opłacalność wykorzystania ich w przyszłym rozwoju bazy danych.


1
Też chciałbym to wiedzieć ... Chciałbym usłyszeć, co ludzie mają do powiedzenia.
wałek klonowy

Odpowiedzi:


2

Jak zwykle...

To zależy

Czy masz jednostkę domeny używaną w więcej niż jednym miejscu, której wspieranie natywnie wymagałoby dużego wysiłku i / lub zbędnych ograniczeń i zachowań ?

Jeśli tak, usuń domenę. Jeśli nie, nie przejmuj się.

Uważam, że konieczne jest utworzenie typu SQL Server zdefiniowanego przez użytkownika dokładnie raz, w oparciu o powyższą heurystykę. Już nawet nie pamiętam, co to było - ale zaoszczędziło więcej pracy niż spowodowało.


5

Jako użytkownik SQL Server i C # nie korzystałem z typów zdefiniowanych przez użytkownika w bazie danych, ponieważ jestem o wiele bardziej wydajny po stronie aplikacji. Zdarzenie po ORM, takich jak LINQ to SQL i Entity Framework, moje wykorzystanie możliwości serwera znacznie się zmniejszyło.

Na przykład użyłem integracji CLR, aby załadować niektóre funkcje konwersji DateTime do SQL Server, aby przenieść gregoriańskie daty do innych formatów, w oparciu o moc globalizacji .NET. Ale teraz sprawy wyglądają inaczej i już tego nie robię. Po prostu ładuję dane i dokonuję transformacji bezpośrednio w mojej warstwie aplikacji.

Po prawie 4 latach programowania i inspekcji wszystkich zespołów, o których mogę myśleć, nie znalazłem próbki użycia typów zdefiniowanych przez użytkownika. Nie widziałem tego także w wielu blogach .NET.

Chociaż nie oznacza to, że ludzie nie korzystają z domeny bazy danych , to z pewnością oznacza, że ​​przynajmniej korzystanie z domeny bazy danych nie jest tak powszechne.


„Nie korzystałem z typów zdefiniowanych przez użytkownika w bazie danych, ponieważ jestem dość potężny po stronie aplikacji” : więc zamiast tego używasz ograniczeń? Nie rozumiem, czym różni się od punktu widzenia aplikacji?
Arseni Mourzenko

@MainMa, na przykład, nie tworzę klasy Student w warstwie bazy danych. Po prostu tworzę tabelę uczniów ze wszystkimi pierwotnymi typami danych, takimi jak liczba całkowita i ciąg, a następnie przy użyciu ORM mapuję dowolny rekord na obiekt w aplikacji.
Saeed Neamati,

Zrozumiany. Masz rację.
Arseni Mourzenko

3

Istnieje już szczegółowa odpowiedź na temat przepełnienia stosu. W większości się z tym zgadzam, ale nie z podanym przykładem cytuję:

„Na przykład definiuję„ GenderType ”(char (1), nie dopuszczający wartości null, zawierający„ M ”lub„ F ”), który zapewnia, że ​​w polu Płeć dozwolone są tylko odpowiednie dane.”

Osobiście czuję się bardziej komfortowo ustawiając char(1)typ i definiując ograniczenie dla kolumny. Kiedy ograniczenie zostanie naruszone, wiem dokładnie, gdzie szukać, aby znaleźć to, co zrobiłem źle. Jest również bardziej znany niż typy zdefiniowane przez użytkownika, więc baza danych, która wykorzystuje tylko ograniczenia, byłaby łatwiejsza do zrozumienia dla początkującego.

Oczywiście, to tylko osobista opinia. Inni ludzie twierdzą, że in ('M', 'F')ograniczenie nie jest samo-dokumentujące i może być bardzo niejasne dla świeżego programisty, który odkrywa bazę danych.

IMO, użyj typów zdefiniowanych przez użytkownika dla bardziej skomplikowanych typów i ograniczeń dla czegoś podstawowego. Ponadto, gdy nie możesz łatwo znaleźć wyraźnej nazwy typu, istnieje szansa, że ​​ograniczenie będzie lepiej pasować.


Co z hermafrodytami?
Wyatt Barnett,

Czy interseksualny? Lub transpeople?
Broam

1

Nie korzystałem z tej funkcji sam, ale myślę, że musisz upewnić się, że:

  1. Jeśli baza danych jest używana przez jeden system, może nie mieć sensu korzystanie z tej funkcji i dodawanie logiki sprawdzania w warstwie biznesowej lub jej odpowiedniku. Zapewni to większą elastyczność sprawdzania poprawności (powiedzmy przy użyciu wyrażeń regularnych) i pozwoli na zawarcie całej logiki sprawdzania poprawności w jednym miejscu. Jeśli twoja baza danych jest współużytkowana przez kilka systemów, możesz zamiast tego użyć wyzwalaczy, które są odpowiednie dla tego zadania.

  2. Nie jestem pewien, czy UDT pozwala dostosować komunikaty o błędach zwracane do klienta, gdy wystąpi błąd sprawdzania poprawności.

  3. UDT są bardzo przydatne, jeśli ta sama reguła sprawdzania poprawności ma zastosowanie do kilku kolumn. Moim zdaniem nie uważam tego za bardzo częsty przypadek w aplikacjach biznesowych ze znormalizowanym projektem bazy danych.

Możesz być zainteresowany sprawdzeniem „Jaki jest sens typów zdefiniowanych przez użytkownika [SQL Server]?” artykuł na blogu.


1
+1 za trzeci punkt. Pisanie tego samego ograniczenia raz po raz, tak jak ja, nie jest najlepszą rzeczą, szczególnie gdy ograniczenie może się zmieniać w czasie, wymagając zmiany w kilku miejscach.
Arseni Mourzenko

0

Kiedy mówisz „nie wszystkie bazy danych obsługują to”, myślę, że lepszym sposobem na przedstawienie tego jest:

Każda duża baza danych obsługuje to, ponieważ intensywnie obsługują wyzwalacze, funkcje i inne zaawansowane funkcje.

To prowadzi nas do wniosku, że jest to część zaawansowanego SQL i w pewnym momencie ma sens.

Do people actually use domains in their database designs?

Jest to mniej możliwe ze względu na wymagany szeroki zasięg (biorąc pod uwagę operatorów, indeksy itp.)

If so to what extent?

Ponownie, jakkolwiek ograniczone, jeśli istniejący typ w połączeniu z nieco dodatkową zdefiniowaną logiką (tj. Kontrole itp.) Może załatwić sprawę, po co posuwać się tak daleko?

How useful are they?

Całe mnóstwo. Rozważmy przez sekundę niezbyt dobry DBMS, taki jak MySQL, który wybrałem dla tego przykładu z jednego powodu: brak dobrej obsługi typu inet (adres IP).

Teraz chcesz napisać aplikację, która koncentruje się głównie na danych IP, takich jak zakresy i tak dalej, i utkniesz z domyślnym typem i jego ograniczoną funkcjonalnością, napiszesz dodatkowe funkcje i operatory (takie jak te obsługiwane natywnie w PostgreSQL dla przykład) lub napisz o wiele bardziej złożone zapytania dla każdej potrzebnej funkcjonalności.

Jest to przypadek, w którym łatwo uzasadnisz czas poświęcony na zdefiniowanie własnych funkcji (inet >> inet w PostgreSQL: zakres zawarty w operatorze zakresu).

W tym momencie uzasadniono już rozszerzenie obsługi typu danych, istnieje tylko jeden krok do zdefiniowania nowego typu danych.

Teraz wracamy do PostgreSQL, który ma naprawdę ładne wsparcie typu, ale nie ma niepodpisanego int .. którego potrzebujesz, ponieważ naprawdę martwisz się pamięcią / wydajnością (kto wie ...), więc musisz go dodać, a także operatorzy - chociaż oczywiście wynika to głównie z istniejących operatorów int.

What pitfalls have you encountered?

Nie bawię się tym, ponieważ do tej pory nie miałem projektu, który wymagałby i uzasadniał czas potrzebny na to.

Największymi problemami, jakie widzę, byłyby na nowo wymyślenie koła, wprowadzenie błędów w „bezpiecznej” warstwie (db), niekompletne wsparcie typu, które zrozumiesz dopiero kilka miesięcy później, gdy twój CONCAT (obsada * AS varchar) zawiedzie, ponieważ ty nie zdefiniował obsady (nowy typ jako varchar) itp.

Istnieją odpowiedzi mówiące o „niezbyt często” itp. Zdecydowanie są i powinny być rzadkie (w przeciwnym razie oznacza to, że w dbms brakuje wielu ważnych typów), ale z drugiej strony należy pamiętać, że (dobra) db jest zgodna z ACID ( w przeciwieństwie do aplikacji) i że wszystko, co dotyczy spójności, jest tam lepiej przechowywane.

Istnieje wiele przypadków, w których logika biznesowa jest obsługiwana w warstwie oprogramowania i można to zrobić w języku SQL, gdzie jest to bezpieczniejsze. Twórcy aplikacji czują się bardziej komfortowo w warstwie aplikacji i często unikają lepszych rozwiązań zaimplementowanych w SQL, nie należy tego uważać za dobrą praktykę.

UDT mogą być dobrym rozwiązaniem do optymalizacji, dobry przykład podano w innej odpowiedzi na temat typu m / f za pomocą char (1). Gdyby to był UDT, mógłby to być boolean (chyba że chcemy zaoferować trzecią i czwartą opcję). Oczywiście wszyscy wiemy, że tak naprawdę nie jest to optymalizacja z powodu narzutu kolumny, ale istnieje możliwość.


Określona funkcja (DOMAIN) nie jest obsługiwana przez wszystkie bazy danych. Tak, używając wyzwalaczy, ograniczeń i funkcji, możesz je emulować , ale to nie czyni z niego obsługiwanej funkcji.
Oded

Każda duża baza danych obsługuje to, ponieważ intensywnie obsługują wyzwalacze, funkcje i inne zaawansowane funkcje. Niektóre naprawdę lekkie / gburowate nie, i nikomu, kto ich używa, nie obchodzi, ponieważ ich ograniczenia rozciągają się znacznie dalej niż typy specyficzne dla użytkownika;)
Morg.

0

Na papierze UDT to świetna koncepcja. Pozwalają one naprawdę znormalizować DB (np. Gdy masz dwie kolumny, które są od siebie zależne), a także enkapsulować logikę związaną z twoim nowym typem.

W praktyce cena, którą płacisz (dzisiaj) jest zbyt wysoka. Oczywiście jest to narzut związany z programowaniem, ale poza tym tracisz wsparcie z różnych narzędzi ORM i narzędzi do raportowania oraz znacznie zwiększasz ogólną złożoność rozwiązania. Nie ma zbyt wielu programistów, którzy są blisko zaznajomieni z UDT i nigdy nie widziałem zarządzanych UDT poza przykładami.

Jednym z najlepszych przykładów typu, który najlepiej jest wykonać jako UDT (jeśli jeszcze nie istniał), musiałby być hierarchyid( link MSDN ). Aby pozostać wydajnym, przechowuje swoją wartość w formacie binarnym (w przeciwieństwie do zwykłych niestandardowych implementacji varchar), co byłoby kłopotliwe w utrzymaniu bez funkcji tego typu. 10 lub więcej metod, które zapewnia ten typ, najlepiej zapewnia się jako część typu, w przeciwieństwie do funkcji zewnętrznych. Zastanowiłbym się nad użyciem niestandardowego zarządzanego UDT w przypadkach takich jak ten - gdzie można uzyskać znaczną korzyść, zapewniając wydajną i zgrabną implementację jako osobny typ.


0

Bardziej praktyczne pytanie / odpowiedź. Czy Twoja firma pozwala z niego korzystać?

Czy Twoja firma współpracuje z kilkoma markami DBSQL, które obsługują różne DDL?

Każda marka bazy danych może oferować dobre dodatkowe funkcje, takie jak typy zdefiniowane przez użytkownika, ale jeśli Twoja firma korzysta z kilku baz danych, możesz mieć problemy z niestandardowymi funkcjami.

Jeśli firma jest tylko Ty lub możesz zdecydować, których baz danych i funkcji będziesz używać, możesz użyć DDL

Pracuję z kilkoma projektami, w których użyteczny może być typ zdefiniowany przez użytkownika, ale powinienem trzymać się bardziej standardowych funkcji, ponieważ mieliśmy do czynienia z kilkoma bazami danych. (s).

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.