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ść.