如何限制 SQLite / MySQL 中的列值

发布于 2024-11-16 01:39:08 字数 212 浏览 7 评论 0原文

我想限制表中的列值。例如,列值只能是 carbikevan。我的问题是如何在 SQL 中实现这一点,在数据库端执行此操作是一个好主意还是应该让应用程序限制输入?

我还打算在将来添加或删除更多值,例如 truck

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

I would like to restrict a column value in a table. For example, the column values can only be car or bike, or van. My question is how do you achieve this in SQL, and is it a good idea to do this on the DB side or should I let the application restrict the input?

I also have the intention to add or remove more values in the future, for example, truck.

The types of Databases I am using are SQLite and MySQL.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

菩提树下叶撕阳。 2024-11-23 01:39:08

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

通过这种结构,我肯定会选择在数据库级别而不是应用程序级别进行调节。

Add a new table containing these means of transport, and make your column a foreign key to that table. New means of transport can be added to the table in future, and your column definition remains the same.

With this construction, I would definitively choose to regulate this at the DB level, rather than that of the application.

咋地 2024-11-23 01:39:08

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

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

请参阅 MySQL 参考:ENUM 类型

要添加到此,我发现限制数据库端应用程序端总是更好。一个枚举加上一个选择框就可以了。

For MySQL, you can use the ENUM data type.

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

See MySQL Reference: The ENUM Type

To add to this, I find it's always better to restrict on the DB side AND on the app side. An Enum plus a Select box and you're covered.

谁人与我共长歌 2024-11-23 01:39:08

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

在 SQLite 中:

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

在 MySQL 中:

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

Yes, it is recommended to add check constraints. Check constraints are used to ensure the validity of data in a database and to provide data integrity. If they are used at the database level, applications that use the database will not be able to add invalid data or modify valid data so the data becomes invalid, even if the application itself accepts invalid data.

In SQLite:

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

In MySQL:

create table MyTable
(
    name ENUM('car', 'bike', 'van')
);
赴月观长安 2024-11-23 01:39:08

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

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

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

You would use a check constraint. In SQL Server it works like this

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

I'm not sure if this is ANSI standard but I'm certain that MySQL has a similar construct.

久随 2024-11-23 01:39:08

如果您想进行数据库端验证,可以使用触发器。有关 SQLite,请参阅,以及此 MySQL 的详细操作方法

所以问题实际上是您是否应该使用数据库验证。如果您有多个客户端——无论它们是不同的程序,还是多个用户(可能具有不同版本的程序)——那么采用数据库路线绝对是最好的。数据库(希望)是集中式的,因此您可以解耦验证的一些细节。在您的特定情况下,您可以验证插入到列中的值是否包含在仅列出有效值的单独表中。

另一方面,如果您对数据库缺乏经验,计划针对多个不同的数据库,并且没有时间培养专业知识,那么简单的应用程序级验证也许是最方便的选择。

If you want to go with DB-side validation, you can use triggers. See this for SQLite, and this detailed how-to for MySQL.

So the question is really whether you should use Database validation or not. If you have multiple clients -- whether they are different programs, or multiple users (with possibly different versions of the program) -- then going the database route is definitely best. The database is (hopefully) centralized, so you can decouple some of the details of validation. In your particular case, you can verify that the value being inserted into the column is contained in a separate table that simply lists valid values.

On the other hand, if you have little experience with databases, plan to target several different databases, and don't have the time to develop expertise, perhaps simple application level validation is the most expedient choice.

温柔女人霸气范 2024-11-23 01:39:08

为上面的 @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问题的范围,但还要注意,在设置外键约束时,应该考虑子表(ops_original_table)中的列会发生什么情况,如果父表值 (vehicle_types) 被删除或更新。请参阅此页面了解信息

To add some beginner level context to the excellent answer of @NGLN above.

First, one needs to check the foreign key constraint is active, otherwise sqlite won't limit to the input to the column to the reference table:

PRAGMA foreign_key;

...which gives a response of 0 or 1, indicating on or off.

To set the foreign key constraint:

PRAGMA foreign_keys = ON;

This needs to be set to ensure that sqlite3 enforces the constraint.

I found it simplest to just set the primary key of the reference table to be the type. In the OP's example:

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

Then, one can insert 'car', 'bike' etc into the vehicle_types table (and more in the future) and reference that table in the foreign key constraint in the child table (the table in which the OP wished to reference the type of vehicle):

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);

Outwith the scope of the OP's question but also take note that when setting up a foreign key constraint thought should be given to what happens to the column in child table (ops_original_table) if a parent table value (vehicle_types) is deleted or updated. See this page for info

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文