Khi bạn nói "không phải tất cả các cơ sở dữ liệu đều hỗ trợ điều này", tôi nghĩ cách tốt hơn để đặt nó là như sau:
Mỗi cơ sở dữ liệu chính đều hỗ trợ điều này, vì chúng hỗ trợ kích hoạt, chức năng và các tính năng nâng cao khác một cách rộng rãi.
Điều này đưa chúng ta đến kết luận rằng đây là một phần của SQL nâng cao và có ý nghĩa tại một số điểm.
Do people actually use domains in their database designs?
Càng ít có thể, do phạm vi bảo hiểm rộng rãi cần thiết (xem xét các toán tử, chỉ mục, v.v.)
If so to what extent?
Một lần nữa, hạn chế đến mức có thể, nếu một loại hiện có kết hợp với một chút logic được xác định bổ sung (nghĩa là kiểm tra, v.v.) có thể thực hiện thủ thuật, tại sao lại đi xa đến vậy?
How useful are they?
Toàn bộ rất nhiều. Chúng ta hãy xem xét một giây một DBMS không tốt như MySQL, mà tôi đã chọn cho ví dụ này vì một lý do: nó thiếu hỗ trợ tốt cho loại inet (địa chỉ IP).
Bây giờ bạn muốn viết một ứng dụng chủ yếu tập trung vào dữ liệu IP như phạm vi và tất cả những thứ đó, và bạn bị mắc kẹt với loại mặc định và chức năng giới hạn của nó, bạn sẽ viết các hàm và toán tử bổ sung (như các hàm được hỗ trợ trong postgreQuery cho ví dụ) hoặc viết các truy vấn phức tạp hơn nhiều cho mọi chức năng bạn cần.
Đây là trường hợp bạn sẽ dễ dàng chứng minh thời gian dành cho việc xác định các chức năng của riêng mình (inet >> inet trong PostgreQuery: phạm vi có trong toán tử phạm vi).
Tại thời điểm đó, bạn đã biện minh cho việc mở rộng hỗ trợ kiểu dữ liệu, chỉ có một bước khác để xác định kiểu dữ liệu mới.
Bây giờ hãy quay lại PostgreSQL có hỗ trợ loại thực sự tốt nhưng không có int unsign .. mà bạn cần, bởi vì bạn thực sự quan tâm đến việc lưu trữ / hiệu suất (ai biết ...), bạn cũng sẽ cần thêm nó cũng như toán tử - mặc dù tất nhiên điều này chủ yếu xuất phát từ các toán tử int hiện có.
What pitfalls have you encountered?
Tôi không chơi xung quanh với điều đó cho đến nay tôi chưa có một dự án nào cả hai yêu cầu và biện minh cho thời gian cần thiết cho việc này.
Các vấn đề lớn nhất mà tôi có thể thấy đi kèm đó là phát minh lại bánh xe, giới thiệu các lỗi trong lớp "an toàn" (db), hỗ trợ loại không đầy đủ mà bạn sẽ chỉ nhận ra vài tháng sau khi CONCAT (cast * AS varchar) thất bại vì bạn đã không định nghĩa một diễn viên (newtype là varchar), v.v.
Có những câu trả lời nói về "không phổ biến", v.v ... Chắc chắn đây là những điều nên và không phổ biến (nếu không, điều đó có nghĩa là dbms thiếu rất nhiều loại quan trọng), nhưng mặt khác, người ta nên nhớ rằng một db (tốt) tuân thủ ACID ( không giống như một ứng dụng) và rằng bất cứ điều gì liên quan đến tính nhất quán sẽ được giữ tốt hơn ở đó.
Có nhiều trường hợp logic nghiệp vụ được xử lý trong lớp phần mềm và nó có thể được thực hiện bằng SQL, nơi an toàn hơn. Các nhà phát triển ứng dụng có xu hướng cảm thấy thoải mái hơn trong lớp ứng dụng và thường tránh các giải pháp tốt hơn được triển khai trong SQL, điều này không nên được coi là thực tiễn tốt.
UDT có thể là một giải pháp tốt để tối ưu hóa, một ví dụ hay được đưa ra trong một câu trả lời khác về loại m / f sử dụng char (1). Nếu đó là một UDT, nó có thể là một boolean thay thế (trừ khi chúng tôi muốn cung cấp các tùy chọn thứ ba và thứ tư). Tất nhiên tất cả chúng ta đều biết điều này không thực sự tối ưu hóa do chi phí cột, nhưng khả năng là có.