简体   繁体   English

在mysql中创建表约束

[英]create table constraint in mysql

I have a table in which I have some columns a,b,c and for each column there is another column ,say, (x,y,z) which is dependent on a,b,c respectively. 我有一个表格,其中我有一些列a,b,c并且对于每列,还有另一列,例如, (x,y,z) ,它们分别依赖于a,b,c

x,y,z will have value 1 if a,b,c has any value and will contain null if a,b,c has null . 如果a,b,c具有任何值,则x,y,z将具有值1 a,b,c并且如果a,b,c has null ,则将包含a,b,c has null

For an example Lets say, The values stored in a is 2 and x is the column dependent on it. 举个例子,让我们说,存储在a的值是2x是依赖于它的列。 So x will have value as 1 . 所以x值为1

If the values stored in a is null then x will have value as null . 如果存储在a值为nullx值为null

so is there a way in which we can declare this constraint at the time of table creation. 那么有没有一种方法可以在创建表时声明这个约束。

Please suggest anything other than triggers. 除了触发器之外,请提出建议。

If the purpose of x , y and z is to simplify some queries then rather than having x , y and z as columns on your table you could also consider using a view to do this eg 如果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;

and then base your other queries on this view instead of directly on the table. 然后将您的其他查询基于此视图,而不是直接在表上。

The constraint you are looking for is the check constraint. 您要查找的约束是检查约束。

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

Unfortunately this isn't implemented in MySQL . 不幸的是, 这在MySQL中没有实现 There is an open bug report dating back to 2004 for this feature so don't expect to see it any time soon. 有一个可以追溯到2004年的这个功能的开放式错误报告 ,所以不要指望很快就能看到它。

Others have answered that you can use triggers or views to achieve the desired result, and these are the correct answers for MySQL. 其他人已回答您可以使用触发器或视图来实现所需的结果,这些是MySQL的正确答案。

You can also partially constrain your data using some simple tricks: 您还可以使用一些简单的技巧来部分约束数据:

  • Set the data type of x, y, z to enum('1') . x, y, z的数据类型设置为enum('1') This will prevent values other than null and '1' from being inserted but won't ensure the values are correct. 这将阻止插入除null'1'以外的null ,但不能确保值正确。
  • If a, b, c have a limited range of possible values you can create foreign key constraints to other tables and populate those tables with every possible value of a, b, c 如果a, b, c具有有限范围的可能值,则可以为其他表创建外键约束,并使用a, b, c每个可能值填充这些表。
  • You can create an event to update x, y, z on a schedule (eg once every hour or once a day). 您可以创建一个事件来按计划更新x, y, z (例如每小时一次或每天一次)。 The values for x, y, z can be corrected if they wrong. 如果错误x, y, z可以纠正x, y, z的值。

You can see the check constraint in action with PostGreSQL here 你可以在这里看到PostGreSQL的检查约束

If you need further advice please explain why triggers are inappropriate for your task. 如果您需要进一步的建议,请解释为什么触发器不适合您的任务。

MySQL doesn't handle CONSTRAINTS per-se, but you could implement a similar behavior using a TRIGGER on the BEFORE INSERT and BEFORE UPDATE events. MySQL本身不处理CONSTRAINTS ,但您可以在BEFORE INSERTBEFORE UPDATE事件上使用TRIGGER实现类似的行为。 You will, however, have to rely on some other table-level constrains ( NOT NULL ) to get it working, as per this other question on SO . 但是,您将不得不依赖其他一些表级约束( NOT NULL )来使其工作,正如SO上的另一个问题

In your very specific case, it looks a lot like you would want to use the trigger to calculate the value of your x, y, z values in the trigger, rather than using it to prevent insertion of data with "improper" values - but your question does not make this point unambiguously clear, so it depends on what you really want. 在您的特定情况下,它看起来很像您希望使用触发器来计算触发器中x, y, z值的值,而不是使用它来防止插入具有“不正确”值的数据 - 但是你的问题没有明确说明这一点,所以这取决于你真正想要的是什么。

Yes, you can use triggers for this. 是的,您可以使用触发器

From the Trigger syntax chapter: Trigger语法章节:

If a BEFORE trigger fails, the operation on the corresponding row is not performed 如果BEFORE触发器失败,则不执行相应行的操作

Although the scenario you describe implies that the data is not normalized. 虽然您描述的方案暗示数据未规范化。

Besides constraints, you could achieve a similar result by not storing at all the x, y, z columns and using a view: 除了约束之外,您可以通过存储所有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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM