如果列设置为x,则为SQL唯一约束

时间:2011-01-19 18:04:43

标签: mysql sql constraints unique

如果特定列具有特定值,SQL中是否有一种方法可以创建列必须唯一的约束?

示例:行并未真正删除,但在数据库中标记为“已删除”。在“未删除”行中,ValueA必须是唯一的:

ID    ValueA          ValueB            Deleted
-----------------------------------------------------
1     'foo'           10               0
2     'bar'           20               0
3     'bar'           30               1
4     'bar'           40               1
5     'foo'           50               0 --NOT ALLOWED

我想到了类似CHECK约束的东西,但我不知道该怎么做。

5 个答案:

答案 0 :(得分:4)

使用SQL92

这是不可能的,可能是你可以使用触发器实现某些东西

答案 1 :(得分:1)

你能改变一下设计吗?

在我看来,你有一个“东西”列表。对于每个ValueA,任何时候都有一个活跃的“thingy”。这可以最好地建模如下:

  1. 从主Thingies表中删除ValueA并删除。

  2. 使用列ValueA和ID创建一个新表ActiveThingies。通过使ValueA成为唯一或主键来保护此表。 (您可能还需要使ID唯一,具体取决于单个ID是否可以代表超过1个ValueA)。

  3. 现在,使用ActiveThingies表来随时控制哪条记录是最新的。要更改“foo”的活动(未删除)记录,请在ActiveThingies中更新它的ID列。

    要获取未删除项目列表,请加入两个表格。

    但是,使用此设计,您将失去记住“已删除”“thingies”的ValueA的能力。如果您需要记住这些值,您还需要在Thingies中包含ValueA列。

答案 2 :(得分:0)

MySQL忽略了CHECK约束,因此您不能像在其他数据库中那样在MySQL中执行此操作。

这是一个黑客。对valueA +删除的唯一约束。删除行时不能只使用1,它们必须是1,2,3 ......

这至少可以让你在MySQL中实现服务器端,但是引入了一个步骤。标记要删除的行时,必须首先找到max(已删除),添加1,并在标记删除时插入该值。

答案 3 :(得分:0)

将表拆分为两个表:一个在ValueA上具有UNIQUE约束,另一个不在。使用视图+触发器组合两个表。类似的东西:

CREATE TABLE _Active (
    ID       INTEGER,
    ValueA   VARCHAR(255) UNIQUE,
    ValueB   INTEGER
);

CREATE TABLE _Deleted (
    ID       INTEGER,
    ValueA   VARCHAR(255), /* NOT unique! */
    ValueB   INTEGER
);

CREATE VIEW Thingies AS
    SELECT ID, ValueA, ValueB, 0 AS Deleted FROM _Active
UNION ALL
    SELECT ID, ValueA, ValueB, 1 AS Deleted FROM _Deleted;

CREATE TRIGGER _trg_ii_Thingies_Active
    INSTEAD OF INSERT ON Thingies
    FOR EACH ROW WHEN NOT NEW.Deleted
BEGIN
    INSERT INTO _Active(ID, ValueA, ValueB)
        VALUES (NEW.ID, NEW.ValueA, NEW.ValueB);
END;

CREATE TRIGGER _trg_ii_Thingies_Deleted
    INSTEAD OF INSERT ON Thingies
    FOR EACH ROW WHEN NEW.Deleted
BEGIN
    INSERT INTO _Deleted(ID, ValueA, ValueB)
        VALUES (NEW.ID, NEW.ValueA, NEW.ValueB);
END;

/* Add triggers for DELETE and UPDATE as appropriate */

(我不确定CREATE TRIGGER语法,但你知道我的意思。)

答案 4 :(得分:0)

此问题有解决方法 - 创建另一列 deleted_on

     deleted_on timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'

并在 ValueA deleted_on 上制作唯一键。

    UNIQUE KEY not_deleted (ValueA, deleted_on)

软删除记录插入NOW()以获取deleted_on

的值时