web-dev-qa-db-ja.com

SQLite / MySQLで列の値を制限する方法

SQLテーブルの列の値を制限したいと思います。たとえば、列の値は「car」、「bike」、「van」のみです。私の質問は、SQLでこれをどのように達成するかです。これをDB側で行うのは良い考えですか、それともアプリケーションに入力を制限させるべきですか。

また、将来的には「トラック」などの値を追加または削除する予定です。

私が使用しているデータベースの種類はSQLiteとMySQLです。

20
Maro

これらの輸送手段を含む新しいテーブルを追加し、列をそのテーブルへの外部キーにします。将来、新しい輸送手段をテーブルに追加することができ、列の定義は同じままです。

この構成では、アプリケーションではなく、DBレベルでこれを規制することを決定的に選択します。

32
NGLN

MySQLの場合、ENUMデータ型を使用できます。

column_name ENUM( 'small'、 'medium'、 'large')

MySQLリファレンス:ENUMタイプ を参照してください。

これに加えて、アプリ側ではDB側[〜#〜]と[〜#〜]で制限する方が常に良いと思います。列挙型と選択ボックスがあれば、カバーされます。

22
nageeb

はい、チェック制約を追加することをお勧めします。チェック制約は、データベース内のデータの有効性を保証し、データの整合性を提供するために使用されます。それらがデータベースレベルで使用される場合、アプリケーション自体が無効なデータを受け入れても、データベースを使用するアプリケーションは無効なデータを追加したり、有効なデータを変更したりできないため、データは無効になります。

SQLiteの場合:

create table MyTable
(
    name string check(name = "car" or name = "bike" or name = "van")
);

MySQLの場合:

create table MyTable
(
    name ENUM('car', 'bike', 'van')
);
8
Alex Aza

チェック制約を使用します。 SQL Serverでは、次のように機能します

ALTER TABLE Vehicles
ADD CONSTRAINT chkVehicleType CHECK (VehicleType in ('car','bike','van'));

これがANSI規格であるかどうかはわかりませんが、MySQLにも同様の構造があると確信しています。

4
Bob Probst

DB側の検証を使用する場合は、トリガーを使用できます。 SQLiteの場合は this を、MySQLの場合はthis 詳細なハウツー を参照してください。

したがって、問題は、データベース検証を使用する必要があるかどうかです。複数のクライアントがある場合(それらが異なるプログラムであろうと、複数のユーザー(プログラムのバージョンが異なる可能性がある)であろうと)、データベースルートを使用するのが間違いなく最善です。データベースは(うまくいけば)一元化されているため、検証の詳細の一部を切り離すことができます。特定のケースでは、列に挿入されている値が、有効な値をリストするだけの別のテーブルに含まれていることを確認できます。

一方、データベースの経験がほとんどなく、複数の異なるデータベースをターゲットにすることを計画していて、専門知識を開発する時間がない場合は、おそらく単純なアプリケーションレベルの検証が最も便利な選択です。

2
Dilum Ranatunga