2011-06-16 82 views
16

我想限制SQL表中的列值。例如,列值只能是“汽车”或“自行车”或“面包车”。我的问题是你如何在SQL中实现这个目标,并且在数据库端执行此操作是一个好主意,或者我应该让应用程序限制输入。如何限制SQLite/MySQL中的列值

我也有打算在将来添加或删除多个值,例如,“卡车”

类型的数据库,我使用的SQLite和MySQL的

回答

30

添加一个包含这些传输方式的新表,并将您的列作为该表的外键。新的交通工具可以添加到表中,并且列定义保持不变。

有了这个构造,我会明确地选择在数据库级调整它,而不是应用程序的调整。

+2

我喜欢这是最好的 - 这是满足“未来添加更多类型”而不进行数据库更改(仅插入新行)的要求的唯一答案 – Bohemian 2011-06-16 04:40:33

+0

同意,数据不是静态的事实证实它应该是查找表而不是“CHECK”约束或等价物。是的,这个数据约束应该在数据库中建模。 – onedaywhen 2011-06-16 05:56:19

17

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

列名ENUM( '小', '中', '大')

MySQL Reference: The ENUM Type

要添加到这一点,我觉得它总是最好的DB侧限制AND在应用程序端。一个枚举加上一个选择框,你被覆盖。

+2

这很难满足轻松 “在未来增加更多类型” 的要求 - 你必须做出改变分贝。问问DBA他会如何激动。 – Bohemian 2011-06-16 04:41:38

+0

你没有提到你不想打扰可怜的DBA添加更多的项目。也许你应该在问题中指出这一点。 – nageeb 2011-06-16 05:13:19

+0

我没有问这个问题。我只是评论你的答案。我虽然没有downvote :) – Bohemian 2011-06-16 07:24:15

2

如果您想要使用DB端验证,您可以使用触发器。对于SQLite,请参阅this,对于MySQL,请参阅detailed how-to

所以问题是你是否应该使用数据库验证或不。如果你有多个客户端 - 无论它们是不同的程序,还是多个用户(可能有不同版本的程序) - 那么去数据库路由绝对是最好的。数据库(希望)是集中式的,所以你可以分解验证的一些细节。在您的特定情况下,您可以验证插入到列中的值是否包含在单独列表中,该列表仅列出有效值。另一方面,如果您对数据库几乎没有经验,计划定位几个不同的数据库,并且没有时间开发专业知识,或许简单的应用程序级别验证是最方便的选择。

4

您将使用检查约束。在SQL Server中,它的工作原理是这样的

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

我不确定这是否是ANSI标准,但我确定MySQL具有类似的构造。

+0

错过了右括号? – faizal 2014-08-23 06:22:40

8

是的,建议添加检查约束。检查约束用于确保数据库中数据的有效性并提供数据完整性。如果在数据库级使用它们,那么即使应用程序本身接受了无效数据,使用该数据库的应用程序也将无法添加无效数据或修改有效数据,从而导致数据无效。

在SQLite的:

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

在MySQL:

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

在SQLite中,你可以说'检查('汽车','自行车','范'))''(名称)''。另外:“ - 引号用于标识符,' - 引用字面值。 – equaeghe 2016-03-23 09:15:59