如何在SQLite / MySQL中限制列值

svgewumm  于 12个月前  发布在  Mysql
关注(0)|答案(6)|浏览(102)

我想限制表中的列值。例如,列值只能是carbikevan。我的问题是如何在SQL中实现这一点,在数据库端这样做是一个好主意还是应该让应用程序限制输入?
我还打算在将来添加或删除更多的值,例如truck
我使用的数据库类型是SQLite和MySQL。

9o685dep

9o685dep1#

添加一个包含这些运输方式的新表,并使您的列成为该表的外键。将来可以向表中添加新的运输方式,并且您的列定义保持不变。
有了这个结构,我肯定会选择在数据库级别而不是应用程序级别对此进行规范。

vqlkdk9b

vqlkdk9b2#

对于MySQL,可以使用ENUM数据类型。

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

字符串
请参阅MySQL Reference: The ENUM Type
除此之外,我发现在数据库端限制和在应用程序端限制总是更好的。一个枚举加上一个选择框,你就被覆盖了。

umuewwlo

umuewwlo3#

是,建议添加检查约束。检查约束用于确保数据库中数据的有效性并提供数据完整性。如果在数据库级别使用检查约束,则使用数据库的应用程序将无法添加无效数据或修改有效数据,从而使数据变为无效,即使应用程序本身接受无效数据。
在SQLite中:

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

字符串
在MySQL中:

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

zaqlnxep

zaqlnxep4#

您可以使用检查约束。

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

字符串
我不确定这是否是ANSI标准,但我肯定MySQL有类似的结构。

wwtsj6pe

wwtsj6pe5#

如果你想使用DB端验证,你可以使用触发器。参见this for SQLite,detailed how-to for MySQL。
所以问题是你是否应该使用数据库验证。如果你有多个客户端--不管他们是不同的程序,还是多个用户(可能有不同版本的程序)--那么走数据库路线肯定是最好的。(希望)集中化,因此您可以解耦验证的一些细节。在您的特定情况下,您可以验证插入到列中的值是否包含在单独的表中,该表仅列出有效值。
另一方面,如果您对数据库几乎没有经验,计划针对几个不同的数据库,并且没有时间发展专业知识,那么简单的应用程序级验证可能是最方便的选择。

wsxa1bj1

wsxa1bj16#

为上面@NGLN的优秀答案添加一些初学者水平的上下文。
首先,需要检查外键约束是否有效,否则sqlite不会限制到引用表的列的输入:

PRAGMA foreign_key;

字符串
...它给出0或1的响应,表示开或关。
要设置外键约束:

PRAGMA foreign_keys = ON;


这需要设置以确保sqlite3强制执行约束。
我发现最简单的方法是将引用表的主键设置为类型。在OP的例子中:

CREATE TABLE IF NOT EXISTS vehicle_types(
    vehicle_type text PRIMARY KEY);


然后,可以将'car','bike'等插入到vehicle_types表中(将来还会有更多),并在子表(OP希望引用车辆类型的表)的外键约束中引用该表:

CREATE TABLE IF NOT EXISTS ops_original_table(
    col_id integer PRIMARY KEY,
    ...many other columns...
    vehicle_type text NOT NULL,
    FOREIGN KEY (vehicle_type) REFERENCES vehicle_types(vehicle_type);


超出了OP问题的范围,但也要注意,在设置外键约束时,应该考虑如果父表值(vehicle_types)被删除或更新,子表(ops_original_table)中的列会发生什么。

相关问题