ドメインへまたはドメインへではない


15

SQL92およびSQL99標準は、DDLコンストラクトを定義しています。すべてのデータベースがこれをサポートしているわけではなく、別の名前を持っているわけでもありません(たとえば、SQL Serverにはユーザー定義型があります)。CREATE DOMAIN

これらにより、データベースで使用される制約されたデータ型を定義し、許可された値に関連するルールを簡素化し、強制することができます。このようなデータ型は、列宣言、ストアドプロシージャや関数への入力および出力などで使用できます。

私が知りたいのですが:

  • データベース設計で実際にドメインを使用していますか?
  • その場合、どの程度ですか?
  • それらはどれほど有用ですか?
  • どのような落とし穴に遭遇しましたか?

これらを将来のデータベース開発で使用する可能性を評価しようとしています。


1
私もこれを知りたいです...私は人々が言わなければならないことを聞くことに興味があります。
maple_shaft

回答:


2

いつものように...

場合によります

ドメインエンティティを複数の場所使用している場合、ネイティブサポートにはかなりの労力や冗長な制約や動作が必要になりますか?

その場合、ドメインは離れています。そうでない場合は、気にしないでください。

上記のヒューリスティックに基づいて、SQL Serverでユーザー定義型を1回だけ作成する必要があることがわかりました。それが何であったかさえ覚えていません-しかし、それはそれが引き起こしたよりも多くの仕事を節約しました。


5

SQL ServerとC#のユーザーとして、データベースではユーザー定義型を使用していません。アプリケーション側ではかなり強力だからです。LINQ to SQLやEntity FrameworkなどのORMの後のイベントでは、サーバー機能の使用が大幅に削減されました。

たとえば、CLR統合を使用してDateTime変換関数をSQL Serverにロードし、.NETのグローバリゼーション機能に基づいてグレゴリオ暦の日付時刻を他の形式に転送していました。しかし、今は状況が異なっており、私はそれをもうしません。アプリケーション層でデータをロードし、変換を行うだけです。

だから、ほぼ4年間のプログラミングと考えられるすべてのチームの検査の後、ユーザー定義型を使用するサンプルは見つかりませんでした。また、多くの.NETブログで実際に動作しているのを見たこともありません。

これは、人々がDatabase Domainを使用しないという意味ではありませんが、少なくともDatabase Domainを使用することはそれほど一般的ではないことを意味します。


「アプリケーション側ではかなり強力なので、データベースではユーザー定義型を使用していません」:代わりに制約を使用しますか?わかりませんが、アプリケーションの観点とどう違うのですか?
アルセニムルゼンコ

たとえば、@ MainMaでは、データベースレイヤーにStudentクラスを作成しません。整数や文字列などのすべてのプリミティブデータ型の学生のテーブルを作成し、ORMを使用して、アプリケーション内のオブジェクトにレコードをマッピングします。
サイードネアマティ

わかった。あなたが正しい。
アルセニムルゼンコ

3

スタックオーバーフローに関する詳細な回答は既にあります。私はほとんど同意しますが、与えられた例には同意しません。

「たとえば、「性別」フィールドで適切なデータのみが許可されることを保証する「GenderType」(char(1)、null不可、「M」または「F」を保持)を定義します。」

個人的には、char(1)タイプの設定と列の制約の定義をより快適に感じています。制約に違反した場合、間違ったことを見つけるためにどこを検索すればよいかが正確にわかります。また、ユーザー定義型よりも知られているため、制約のみを使用するデータベースは初心者にとって理解しやすいでしょう。

もちろん、単なる個人的な意見です。他の人は、in ('M', 'F')制約は自己文書化ではなく、データベースを発見した新鮮な開発者にとって非常にわかりにくいかもしれないと言うでしょう。

IMO、より複雑な型にはユーザー定義型を使用し、基本的なものには制約を使用します。また、型の明示的な名前を簡単に見つけることができない場合、制約がより適切に適合する可能性があります。


雌雄同体はどうですか?
ワイアットバーネット

またはインターセックス?またはトランスピープル?
ブラム

1

私は自分でこの機能を使用していませんが、次のことを確認する必要があると思います。

  1. データベースが単一のシステムで使用されている場合、この機能を使用せずに、ビジネスレイヤーまたはそれに相当するものにチェックロジックを追加することは理にかなっています。これにより、検証の柔軟性が高まり(正規表現の使用など)、すべての検証ロジックを1か所にカプセル化できるようになります。データベースが複数のシステムで共有されている場合、代わりにこのタスクに適したトリガーを使用できます。

  2. 検証エラーが発生したときにUDTでクライアントに返されるエラーメッセージをカスタマイズできるかどうかはわかりません。

  3. 同じ検証ルールが複数の列に適用される場合、UDTは非常に便利です。私の意見では、これは、正規化されたデータベース設計を使用するビジネスアプリケーションでは非常に一般的なケースではないと考えています。

「[SQL Server]ユーザー定義型のポイントは何ですか?」をチェックすることもできます。ブログ記事。


1
3番目のポイントに対して+1。同じ制約を何度も何度も書くのは、特に制約が時間とともに変化する可能性があり、複数の場所で変更する必要がある場合には、最善の方法ではありません。
アルセニムルゼンコ

0

「すべてのデータベースがこれをサポートしているわけではない」と言うとき、それを置くより良い方法は次のとおりだと思います。

トリガー、関数、その他の高度な機能を幅広くサポートしているため、すべての主要なデータベースがこれをサポートしています。

これにより、これは高度なSQLの一部であり、ある時点で理にかなっているという結論に至ります。

Do people actually use domains in their database designs?

広範囲にわたるカバレッジが必要なため(オペレーター、インデックスなどを検討)

If so to what extent?

繰り返しになりますが、既存の型を少し追加の定義済みロジック(チェックなど)と組み合わせてトリックを実行できる場合は、可能な限り制限します。

How useful are they?

たくさんの。MySQLのようなあまり良くないDBMSを1秒間考えてみましょう。これは、1つの理由でこの例のために選びました。inet(IPアドレス)タイプの適切なサポートがありません。

範囲などすべてのIPデータに主に焦点を当てたアプリケーションを作成し、デフォルトのタイプとその制限された機能に縛られている場合、追加の関数と演算子(postgreSQLでネイティブにサポートされているような例)または必要なすべての機能に対してより複雑なクエリを記述します。

これは、独自の関数(PostgreSQLのinet >> inet:範囲演算子に含まれる範囲)の定義に費やす時間を簡単に正当化できる場合です。

その時点で、データ型のサポートを拡張することはすでに正当化されています。新しいデータ型を定義するための手順は他に1つしかありません。

PostgreSQLに戻りましょう。これは本当に素晴らしい型のサポートを持っていますが、必要なunsigned intはありません。ストレージ/パフォーマンス(...を知っている)を本当に心配しているので、演算子-もちろん、これは主に既存のint演算子に由来します。

What pitfalls have you encountered?

これまでは、これに必要な時間を必要とする正当な理由を持つプロジェクトを持っていなかったので、いじくり回していません。

私が目にする最大の問題は、車輪の再発明、「安全な」層(db)のバグの導入、不完全な型サポートです。これは、あなたがCONCAT(cast * AS varchar) cast(newtype as varchar)などを定義しませんでした。

「珍しい」などについて話している答えがあります。間違いなくこれらは珍しいことではないはずです(そうでなければdbmsには多くの重要なタイプが欠けていることを意味します)が、一方で、アプリケーションとは異なります)、一貫性に関連するものはすべてそこに保持される方がよいこと。

ビジネスロジックがソフトウェアレイヤーで処理され、SQLで実行でき、より安全な場合が多くあります。アプリ開発者は、アプリケーション層でより快適に感じる傾向があり、多くの場合、SQLで実装されたより良いソリューションを避けます。これは、良い習慣と見なされるべきではありません。

UDTは最適化のための良い解決策になる可能性があります。char(1)を使用したm / fタイプに関する別の回答で良い例を示します。UDTであった場合、代わりにブール値を使用できます(3番目と4番目のオプションを提供したい場合を除く)。もちろん、これは列のオーバーヘッドのために実際には最適化ではないことを知っていますが、可能性はあります。


特定の機能(ドメイン)は、すべてのデータベースでサポートされているわけではありません。はい、トリガー、制約、および関数を使用してエミュレートできますが、サポートされている機能にはなりません。
-Oded

トリガー、関数、その他の高度な機能を広範囲にサポートしているため、すべての主要なデータベースがこれをサポートしています。いくつかの本当に軽快な/クラッピーなものはそうではなく、それらを使用する人は、ユーザー固有のタイプよりもはるかに制限が広がっているので気にしません;)
モルグ。

0

紙上では、UDTは素晴らしい概念です。DBを本当に正規化することができ(たとえば、互いに依存する2つの列がある場合)、新しいタイプに関連するロジックをカプセル化することもできます。

実際には、(今日)支払う価格が高すぎます。明らかに開発のオーバーヘッドがありますが、それ以外に、さまざまなORMおよびレポートツールからのサポートが失われ、ソリューションの全体的な複雑さが大幅に増加します。UDTに精通している開発者はあまりいないので、例以外で使用されるマネージUDTを見たことはありません。

UDTとして最適に実行される型の最良の例の1つ(存在しない場合)は、hierarchyidMSDN link)でなければなりません。効率を維持するために、値をバイナリ形式で保存します(通常のvarcharカスタム実装とは対照的に)。これは、型の関数なしで維持するのが面倒です。型が提供する10個程度のメソッドも、外部関数とは対照的に、型の一部として最適に提供されます。このような場合にカスタム管理UDTを使用することを検討します-効率的できちんとした実装を別のタイプとして提供することで大きなメリットが得られます。


0

より実用的な質問/回答。あなたの会社はそれを使用することを許可していますか?

あなたの会社は、異なるDDLを処理するいくつかのDBSQLブランドと協力していますか?

各データベースブランドは、ユーザー定義型などの優れた追加機能を提供する場合がありますが、会社で複数のDBを使用している場合は、非標準の機能に問題がある可能性があります。

会社があなただけの場合、または使用するデータベースと機能を決定できる場合は、DDLを使用できます

私は、ユーザー定義型が役立つ可能性のあるいくつかのプロジェクトで作業していますが、いくつかのDBを処理する必要があるため、より標準的な機能に固執する必要があります。(s)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.