MySQL行锁深入研究
做项目时由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图书借阅系统。假设
id=1
的这本书库存为
1
,但是有
2
个人同时来借这本书,此处的逻辑为
Select restnum from book where id =1 ;
-- 如果 restnum 大于 0 ,执行 update
Update book set restnum=restnum-1 where id=1 ;
问题就来了,当
2
个人同时来借的时候,有可能第一个人执行
select
语句的时候,第二个人插了进来,在第一个人没来得及更新
book
表的时候,第二个人查到数据了,其实是脏数据,因为第一个人会把
restnum
值减
1
,因此第二个人本来应该是查到
id=1
的书
restnum
为
0
了,因此不会执行
update
,而会告诉它
id=1
的书没有库存
了,可是数据库哪懂这些,数据库只负责执行一条条
SQL
语句,它才不管中间有没有其他
sql
语句插进来,它也不知道要把一个
session
的
sql
语句执行完再执行另一个
session
的。因此会导致并发的时候
restnum
最后的结果为
-1
,显然这是不合理的,所以,才出现锁的概念,
Mysql
使用
innodb
引擎可以通过索引
对数据行加锁。以上借书的语句变为:
Begin;
Select restnum from book where id =1 for update ;
-- 给 id=1 的行加上排它锁且 id 有索引
Update book set restnum=restnum-1 where id=1 ;
Commit;
这样,第二个人执行到
select
语句的时候就会处于等待状态直到第一个人执行
commit
。从而保证了第二个人不会读到第一个人修改前的数据。
那这样是不是万无一失了呢,答案是否定的。看下面的例子。
跟我一步一步来,先建立表
CREATE TABLE `book` (
`id` int(11) NOT NULL auto_increment,
`num` int(11) default NULL,
`name` varchar(0) default NULL,
PRIMARY KEY (`id`),
KEY `asd` (`num`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk
其中
num
字段加了索引
然后插入数据,运行,
insert into book(num) values(11),(11),(11),(11),(11);
insert into book(num) values(22),(22),(22),(22),(22);
然后打开
2
个
mysql
控制台窗口,其实就是建立
2
个
session
做并发操作
********************************************************************
在第一个
session
里运行:
相关文档:
本文从 http://tech.ddvip.com/2009-02/1235627800109815.html 装载,非常感谢作者!
MySQL+PHP产生乱码原因:
◆ MySQL数据库默认的编码是utf8,如果这种编码与你的PHP网页不一致,可能就会造成MySQL乱码;
◆ MySQL中创建表时会让你选择一种编码,如果这种编码与你的网页编码不一致,也可能造成MySQL乱码;
......
现在大概列出如下:
1.数据库的设计
尽量把数据库设计的更小的占磁盘空间.
1).尽可能使用更小的整数类型.(mediumint就比int更合适).
2).尽可能的定义字段为not null,除非这个字段需要null.
3).如果没有用到变长字段的话比如varchar,那就采用固定大小的纪录格式比如char.
4).表的主索引应该尽可能的短.这样的话每条纪录 ......
记了一些用 Windows 的命令行来操作 MySQL 的指令。
摘要
连结 MySQL
->mysql -u username -p
username 是你的帐号名称。
远程连结
->mysql -h hostname -u username -p
hostname 是 MySQL 主机的名称。
显示全部的数据库
SHOW DATABASES;
mysql 是 MySQL 用来储存帐号和权限的数据库,不能删除。
选择 ......
MYSQL有多种存储引擎和表类型,InnoDB和BDB支持事务,如果要使用事务,表的类型就应该是InnoDB.
提高表的性能:
1、用最小的数据类型。占用空间小,节省磁盘空间和内存。
2、表格的主索引要尽可能的短,以明显提高效率。
3、索引最好建在唯一的列上,索引越短,速度越快。
4、多列索引必须包含最左边的前缀才有效。 ......
BLOB
TEXT
一个BLOB或TEXT列,最大长度为65535(2^16-1)个字符。
MEDIUMBLOB
MEDIUMTEXT
一个BLOB或TEXT列,最大长度为16777215(2^24-1)个字符。
LONGBLOB
LONGTEXT
一个BLOB或TEXT列,最大长度为4294967295(2^32-1)个字符。
可通过修改php.ini文件,改变最大长度设置。
; Valid range 0 - 2147483647.  ......