SQL テーブルの列の値を制限したいと考えています。たとえば、列の値は「car」または「bike」または「van」のみです。私の質問は、SQL でこれをどのように達成するのかということです。DB 側でこれを行うのは良い考えですか、それともアプリケーションに入力を制限させるべきですか。
また、将来的には「トラック」などの値を追加または削除する予定です。
私が使用しているデータベースのタイプは、SQLite と MySQL です。
SQL テーブルの列の値を制限したいと考えています。たとえば、列の値は「car」または「bike」または「van」のみです。私の質問は、SQL でこれをどのように達成するのかということです。DB 側でこれを行うのは良い考えですか、それともアプリケーションに入力を制限させるべきですか。
また、将来的には「トラック」などの値を追加または削除する予定です。
私が使用しているデータベースのタイプは、SQLite と MySQL です。
これらの輸送手段を含む新しいテーブルを追加し、列をそのテーブルへの外部キーにします。将来、新しい輸送手段をテーブルに追加できますが、列の定義は変わりません。
この構造では、アプリケーションのレベルではなく、DB レベルでこれを規制することを決定的に選択します。
MySQL の場合、ENUM データ型を使用できます。
column_name ENUM('小', '中', '大')
MySQL リファレンス: ENUM 型を参照してください。
これに加えて、DB 側とアプリ側で制限する方が常に良いことがわかりました。列挙型と選択ボックスがあれば、カバーされます。
はい、チェック制約を追加することをお勧めします。チェック制約は、データベース内のデータの有効性を保証し、データの整合性を提供するために使用されます。それらがデータベース レベルで使用される場合、アプリケーション自体が無効なデータを受け入れたとしても、データベースを使用するアプリケーションは、無効なデータを追加したり、有効なデータを変更してデータを無効にすることができません。
SQLite では:
create table MyTable
(
name string check(name = "car" or name = "bike" or name = "van")
);
MySQL では:
create table MyTable
(
name ENUM('car', 'bike', 'van')
);
チェック制約を使用します。SQL Serverでは、次のように機能します
ALTER TABLE Vehicles
ADD CONSTRAINT chkVehicleType CHECK (VehicleType in ('car','bike','van'));
これが ANSI 標準かどうかはわかりませんが、MySQL にも同様の構造があることは確かです。
DB 側の検証を行いたい場合は、トリガーを使用できます。SQLiteについてはこちらを、MySQLについてはこちらの詳細なハウツーを参照してください。
したがって、問題は、データベース検証を使用する必要があるかどうかです。複数のクライアントがある場合、それらが異なるプログラムであるか、複数のユーザー (プログラムのバージョンが異なる可能性があります) であるかに関係なく、データベース ルートを使用することが間違いなく最適です。データベースは (できれば) 集中管理されているため、検証の詳細の一部を切り離すことができます。特定のケースでは、列に挿入される値が、有効な値を単にリストする別のテーブルに含まれていることを確認できます。
一方、データベースの経験がほとんどなく、複数の異なるデータベースをターゲットにすることを計画しており、専門知識を習得する時間がない場合は、おそらく単純なアプリケーション レベルの検証が最も適切な選択です。