2011-12-07 56 views
6

我有一个表格,其中有一些列a,b,c,每列还有另一列,分别取决于a,b,c(x,y,z)在mysql中创建表约束条件

x,y,z将有价值1如果a,b,c有任何价值,并且将包含空如果a,b,c has null

有关示例比方说, 存储在a的值是2x是依赖于它的列。 所以x的值将为1

如果存储在a中的值是null那么x将具有值null

那么我们可以在表创建时声明这个约束。

请建议除触发器以外的任何其他内容。

+0

家伙感谢您的回复,但请建议除触发器以外的任何其他事情,因为我已经读过,我们可以在创建表中添加一些约束条件.. –

+0

不,您不能。与大多数其他DBMS(Postgre,Oracle,SQL Server ...)不同,MySQL不支持检查约束。 –

回答

7

如果xyz的目的是简化一些查询,然后,而不是xyz为你的表列,你也可以考虑使用视图做到这一点如

create view myview as 
    select a, b, c, 
    if (isnull(a), null, 1) as x, 
    if (isnull(b), null, 1) as y, 
    if (isnull(c), null, 1) as z 
    from mytable; 

然后将您的其他查询基于此视图而不是直接在表上。

+0

嘿,谢谢你的回应,但是在那张桌子上有很多地方插入发生,这是一个巨大的应用程序,我们有两个不同的平台... –

+0

请你详细说明方法,或提供此参考这个。 –

+0

嗨。哪一点不清楚?关于视图的MySQL文档是[here](http://dev.mysql.com/doc/refman/5.6/en/views.html)。 – mikej

1

MySQL本身不处理CONSTRAINTS,但您可以在BEFORE INSERTBEFORE UPDATE事件中使用TRIGGER执行类似的行为。但是,您必须依靠其他一些表级限制(NOT NULL)才能使其工作,如根据this other question on SO

在您的具体情况下,它看起来很像您希望使用触发器计算您的x, y, z值在触发器中的值,而不是用于防止插入具有“不正确”值的数据 - 但你的问题并没有明确地表明这一点,所以这取决于你真正想要的东西。

1

是的,你可以使用triggers这个。

Trigger syntax章:

如果BEFORE触发器失败时,不进行

上的相应行的动作尽管你描述的情况意味着数据不被标准化。

1

而且限制,你可以通过在所有的X,Y,Z列存储和使用视图实现了类似的结果:

CREATE VIEW myView AS 
SELECT 
    a, b, c, 
    (a = a) AS x, 
    (b = b) AS y, 
    (c = c) AS z 
FROM myTable 
4

你正在寻找的约束是检查约束。

CREATE TABLE test 
(
    a varchar(10), 
    b varchar(10), 
    c varchar(10), 
    x integer, 
    y integer, 
    z integer, 
    CONSTRAINT chk_X_Nulls CHECK ((a is null and x is null) or (a is not null and x = 1)), 
    CONSTRAINT chk_Y_Nulls CHECK ((b is null and y is null) or (b is not null and y = 1)), 
    CONSTRAINT chk_Z_Nulls CHECK ((c is null and z is null) or (c is not null and z = 1)) 
); 

不幸的是这在MySQL未实现。这个功能有一个可以追溯到2004年的open bug report,所以不要期望很快就能看到它。

其他人已经回答说,您可以使用触发器或视图来获得所需的结果,这些是MySQL的正确答案。

您还可以使用一些简单的技巧部分限制你的数据:

  • 设置的x, y, z的数据类型enum('1')。这将防止插入除null'1'以外的值,但不能确保值是正确的。
  • 如果a, b, c有一个限制范围的可能值,你可以创建外键约束与其他表和填充这些表与a, b, c
  • 每一个可能的值,您可以创建一个event为按计划更新x, y, z(如每小时一次或一天一次)。如果他们错了,x, y, z的值可以更正。

你可以看到在行动中检查约束在PostgreSQL here

如果您需要进一步的建议,请解释为什么触发器是不适合你的任务。