0

有没有办法使用 MySQL 中的 innodb 引擎限制插入或更新到表中的特定列?我只想通过触发器或过程更新这些列

我想要做的是自动计算这些列,并且不允许直接更改这些列。如果我的方法不正确,请告诉我

4

1 回答 1

3

如果我的方法不正确,请告诉我

你的方法不同寻常,但并非不可能。它是否“正确”将取决于您的问题中未提及的因素:

  • 如果列始终是某个简单表达式的结果,您可以简单地在 each 中指定该表达式SELECT

    SELECT col_a, col_b, LEAST(10*col_a, 5*col_b) AS calculated_column
    FROM   mytbl
    WHERE  ...
    

    或者将结果存储在视图中,这样您就不需要每次都编写表达式:

    CREATE VIEW myview AS
    SELECT col_a, col_b, LEAST(10*col_a, 5*col_b) AS calculated_column
    FROM   mytbl
    

    在这种情况下,要选择结果,只需执行以下操作:

    SELECT * FROM myview WHERE ...
    

    但是,请注意,calculated_column每次从视图中选择时仍会对其进行评估,因此如果它是一个复杂的表达式或您的表很大,可能会导致性能问题。相反,如果您想存储计算结果(以便不需要在每个 上进行评估SELECT),您可以定义覆盖用户提供的任何值的触发器

    CREATE TRIGGER mytbl_insert AFTER INSERT ON mytbl FOR EACH ROW SET
      NEW.calculated_column = LEAST(10*NEW.col_a, 5*NEW.col_b);
    
    CREATE TRIGGER mytbl_update AFTER UPDATE ON mytbl FOR EACH ROW SET
      NEW.calculated_column = LEAST(10*NEW.col_a, 5*NEW.col_b);
    
  • 如果这些列实际上会定期更新,但仅来自存储过程:

    1. 拒绝现有用户更新列的权限:

      REVOKE INSERT (col1, col2), UPDATE (col1, col2) ON mydb.mytbl FROM myuser;
      

      请注意,如果您的用户具有表级或数据库级权限,则需要将其撤销并酌情替换为列级权限。

    2. 创建一个用户,该过程将在该用户下运行:

      GRANT INSERT, UPDATE ON mydb.mytbl TO
      'procuser'@'nonexistent' IDENTIFIED BY PASSWORD '';
      
    3. 定义要在该新用户下运行的过程:

      CREATE DEFINER = 'procuser'@'nonexistent' PROCEDURE ...
      
于 2012-11-17T12:24:30.000 回答