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.
sql
sql-domain
Oded
źródło
źródło
Odpowiedzi:
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.
źródło
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.
źródło
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ę:
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ć.
źródło
Nie korzystałem z tej funkcji sam, ale myślę, że musisz upewnić się, że:
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.
Nie jestem pewien, czy UDT pozwala dostosować komunikaty o błędach zwracane do klienta, gdy wystąpi błąd sprawdzania poprawności.
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.
źródło
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.
Jest to mniej możliwe ze względu na wymagany szeroki zasięg (biorąc pod uwagę operatorów, indeksy itp.)
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?
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.
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ść.
źródło
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.źródło
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).
źródło