策略查询执行

时间:2011-04-17 13:41:38

标签: php mysql

当我在users表中插入新记录时,首先检查电子邮件和昵称尚未添加。同时注册相同数据的另一个用户可能会出现错误结果吗?澄清:

连接1:

 > SELECT * FROM account WHERE username = 'test';

空集(0.00秒)

连接2:

> SELECT * FROM account WHERE username = 'test';

空集(0.00秒)

> INSERT INTO account(username) VALUES ('test');

查询正常,1行受影响(0.01秒)

连接1:

> INSERT INTO account(username) VALUES ('test');

错误。重复密钥

我想知道的是MySQL是否以这种方式工作,通过在查询时运行查询以及使用的最佳实践。 我注意到在转换期间,其他连接所做的更改不可见。为什么?您可以在转换之外使用SELECT ... FOR UPDATE吗?建议大量使用外键来确保数据的完整性?

修改 换一种方式。忽略这个愚蠢的例子。我希望下一个注册用户的年龄大于已经

的所有用户
> SELECT MAX (age) FROM account;

[...检查用户的年龄是否更高......]

> INSERT INTO accounts (age) VALUES ('$ var');

如何确保两个用户拥有相同的野战阵营存在风险?

2 个答案:

答案 0 :(得分:1)

本案例中的最佳做法是创建UNIQUE约束(UNIQUE INDEX)。

当您同时收到2个查询时,您将获得1个查询失败,并能够通过向用户发送正确的消息来处理它。

答案 1 :(得分:0)

Gheez列出了MySQL的所有最佳实践,需要一本书。

我先回答一下:

  

我希望下一个注册用户的年龄大于已经

的所有用户

使用触发器:

DELIMITER $$

CREATE TRIGGER bi_account_each BEFORE INSERT ON account FOR EACH ROW
BEGIN
  declare MaxAge integer;

  SELECT Max(account.age) INTO MaxAge FROM account;
  IF (new.age <= MaxAge) THEN BEGIN
    /* force an error by selecting from a table_that_does_not_exist.*/
    SELECT * FROM 
      ErrFromTrigger_bi_account_each_New_Member_Must_Be_Older_then_The_Last
  END; END IF;

END$$

DELIMITER ;

或存储的功能

DELIMITER $$

CREATE FUNCTION CanInsertInAccount(pAge integer) RETURNS boolean
BEGIN
  declare MaxAge integer;
  declare InsertAllowed boolean;

  SELECT Max(account.age) INTO MaxAge FROM account;
  SET InsertAllowed = (pAge > MaxAge);

  RETURN InsertAllowed;
END$$

DELIMITER ;

请参阅:http://dev.mysql.com/doc/refman/5.1/en/triggers.html
有关触发器的更多信息 并且:http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html
有关存储过程和函数的更多信息。

至于最佳做法,我的列表将是:

  1. 不信任客户输入:将值从php插入MySQL时,始终在每个值上使用mysql_real_escape_string()(或使用PDO {prepared statements}) ;这将保护您免受SQL注入攻击。
  2. 在显示客户输入数据之前删除HTML标记禁止所有HTML。使用htmlspecialchars()将HTML字符转换为HTML实体。所以字符像&lt;和&gt;将标记的开头/结尾标记为&lt;和&gt;。仅使用strip_tags()仅允许某些标签是不够的,因为该函数不会去除onclick或onload等有害属性。
  3. 规范化您的数据库
  4. 使用外键检查
  5. 使用事务,但尽可能多地提交(或回滚)。只将属于一起的东西放在一个交易中。
  6. 使用触发器
  7. 使用存储过程来操作和测试依赖于数据库布局的内容。
  8. 这就是我现在能想到的,这个清单并不完整,这些东西都是个人的。它对我有用,YMMV。