是否可以使用唯一约束,使一个特定列只有一次值?
例如
-----------------------
name | price | default
-----------------------
XYZ | 20 | TRUE
-----------------------
XYZ | 30 | FALSE
-----------------------
XYZ | 40 | FALSE
-----------------------
ABC | 50 | FALSE
-----------------------
因此,在上表中,对于特定的name
值,default
值只能为TRUE一次。名字和名称将有一个独特的约束价格列。
这可能吗?
答案 0 :(得分:1)
我用一个奇怪的aproch解决了这个问题,使用TIMESTAMP
作为标志。
那是用作" 已删除" FLAG。
如果IS为NULL,则寄存器未被删除 - 相反,如果删除(<> NULL),则唯一密钥永远不会发生冲突,从而避免重复寄存器为非扩展的已删除寄存器。
例如在您的情况下:
您永远不会有2行默认值:NULL ,但您可以使用 N TIMESTAMP 并排除时间。
答案 1 :(得分:1)
你可以制作一个触发器来检查是否已经有一个' TRUE'价值,如果采取行动。
请注意,您不能轻易地拒绝"更新。 (参见例如:How to abort INSERT operation in MySql trigger?)。
例如,您可以使用false插入它,并通过设置标志以某种方式保存您的错误。
答案 2 :(得分:1)
在所有三列上放置一个简单的唯一约束是行不通的,因为它允许以下内容:
name | price | default
-----------------------
XYZ | 20 | TRUE
XYZ | 30 | TRUE
XYZ | 40 | FALSE
ABC | 50 | FALSE
在其他SQL引擎中,您可以创建一个检查约束,确保对于每组name
行,default = TRUE
行的数量是< = 1.但是,MySQL确实不支持强制检查约束。
在MySQL中,您可以通过insert
和update
触发器实现此目的:
CREATE TRIGGER `before_insert` BEFORE INSERT ON `tableName`
FOR EACH ROW
BEGIN
DECLARE @sum INT
SELECT @sum = SUM(CASE WHEN [default] = TRUE THEN 1 ELSE 0 END)
FROM tableName
WHERE [name] = new.[name]
IF (@sum = 0 OR new.default = FALSE)
BEGIN
INSERT INTO tableName (name, price, default)
VALUES (new.[name], new.[price], new.[defaul]t)
END
END
同样适用于update
。
答案 3 :(得分:1)
normal方法是提取一个单独的表来保存默认价格:
CREATE TABLE price (
name VARCHAR(255),
price INT,
PRIMARY KEY (name, price)
) ;
CREATE TABLE defaultPrice (
name VARCHAR(255),
price INT,
PRIMARY KEY (name),
FOREIGN KEY(name, price) REFERENCES price(name, price)
);
大多数人会建议引入代理键:
CREATE TABLE item (
id INT PRIMARY KEY,
name VARCHAR(255),
UNIQUE(name)
);
CREATE TABLE price (
itemId INT,
price INT,
PRIMARY KEY (itemId, price),
FOREIGN KEY (itemId) REFERENCES item (id)
) ;
CREATE TABLE defaultPrice (
itemId INT,
price INT,
PRIMARY KEY (itemId),
FOREIGN KEY (itemId, price) REFERENCES price (itemId, price)
);
答案 4 :(得分:0)
这是一种可能适合您需求的解决方法。请考虑以下表定义和唯一约束:
SELECT t1.*, t2.`Linked CODE`
FROM yourTable t1
LEFT JOIN yourTable t2 ON t2.`Product CODE` = t1.`Linked CODE`
WHERE t1.`Product CODE` = 'BI DS110';
在您的应用层中,当CREATE TABLE prices
(
id int NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
price int,
default varchar(255)
)
ALTER TABLE prices ADD UNIQUE idx (id, name, default);
INSERT
default
时FALSE
进行记录时,请始终离开id
列NULL
。这将导致MySQL始终为id
添加唯一值,以便可以输入name
和default
的重复值(即default
值{{1}对于给定的FALSE
,可能会多次出现。
但是,当name
INSERT
为default
的记录为TRUE
时,您应始终使用相同的 id
值。这样可以确保给定的name
只能显示TRUE
一次。