mysql闲谈

mysql中可能产生死锁例如:下面两个事务同时处理StockPrice表
事务一:

START TRANSCATION
updata StockPrice set close = 45.50 where stock_id = 4 and data = '2010-05-01';
updata StockPrice set close = 19.80 where stock_id = 3 and data = ''2010-05-02';
COMMIT

事务二:

START TRANSCATION
updata StockPrice set close = 20.12 where stock_id = 3 and data = '2010-05-02';
updata StockPrice set close = 47.20 where stock_id = 4 and data = ''2010-05-01';
COMMIT   

如果两个事务同时执行了第一行数据,则,同时加锁了该行的数据,接着每个事物都尝试更新第二条数据,却发现即将要更新的数据已经被对方锁定,则陷入死循环,除非有外部的因素介入打破这种死循环,才能解除死锁
自动提交事务的方法:

mysql >show variables like+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.01 sec)
mysql > set autocommit = 1;

当autocommit =0 时候,所以的查询都是在一个事务中,是一个自动提交模式
3.显示表的相关信息

show table status like 'user' \G;
           Name: user
         Engine: InnoDB
        Version: 8
     Row_format: Compact
           Rows: 112
 Avg_row_length: 2
    Data_length: 348
Max_data_length: 0
   Index_length: 160
      Data_free: 944
 Auto_increment: NULL
    Create_time: 2019-06-26 16:45:45
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options: 
        Comment: 
1 row in set (0.01 sec)

4.修改 表的引擎
将mytable的引擎修改为innodb

mysql > ALTER TABLE mytable ENGINE = InnoDB

上述的语法适用任何存储引擎,不过需要的时间长,这是因为mysql会按行将数据从原表复制到一张新表中,在复制期间可能会很消耗所有的IO能力。同时原有在这里插入代码片的表上会加上读锁。
5.创建于查询

mysql >create table innodb_table like myisam_table;
mysql >alter table innodb_table engin = innodb;
mysql >insert into innodb_table select * from myisam_table;

//如果数据量很大的时候可以分批处理

mysql >iSTART TRANSACTION
mysql >insert into innodb_table select * from myisam_table where id between x and y;
mysql >commit        

mysql的show status 命令返回了一些计数器
6. 反范式的优缺点
一个网站,允许用户发送消息,并且一些用户是付费用户的,现在是想看付费用户最近的10条信息,如果是范式化的结构 并且索引发送日期字段published,这个查询看起来如下:

mysql>select message_text,user_name from message inner join user on message.user_id = user.id where user.accout_type = 'premiuvm' order by message.published desc limit 10; 

说明:mysql需要扫描message表的published字段的索引,对于每一行的找到的数据,将需要到user表里检查这个用户是不是付费用户,如果只有一小部分是用户是付费的,这个效率是非常低的。
如果使用反范式组织数据,将两张 表的字段合并一下,并且增加一个索引(account_type,published),就可以不通过这个关联写出这个查询了

mysql> select message_text ,user_name from user_messages where account_type = 'premiuvm' order by published desc limit 10;

9.计算机表
该表主要用来记录点赞数,假设有一个计数器表,只有一行数据,记录网站的点击次数

mysql> create table hit_counter (
		cnt int unsigned not null) engine  = innodb;

网站每次点击的时候都会导致对计数器进行更新

mysql > update hit_counter ( slot tinyint unsigned not null primary key, cnt int unsigned not null) engine  = innodb;

然后选择其中的一行进行更新

mysql > update hit_counter set cnt = cnt + 1 where slot = rand()*100; 

10.手动维护一个哈希值,也可以使用一个触发器实现
创建表如下:

create table pseeduhash
(
	id int unsigned not null auto_increment,
	url varchar(255)not null,
	url_crc int unsigned not null default 0,
	primary key (id)
);

//创建触发器。先临时修改一个语句分隔符,然后这样就可以在触发器定义中使用分号

create trigger pseeduhash_crc_upd before update on pseeduhash for each row begin set new.url_crc = crc32(new.url);

验证一下触发器如何维护哈希索引;

insert into pseeduhash (url) values ('http://www.mysql.com');
select * from pseeduhash ;

11.需要找到最常见的城市列表

select count(*) as cnt,city from sakila.city_demo group by city order by cnt desc limit 10;
//按照city来分组,按照cnt来排序,以降序的方式
现在查找到最频繁出现的城市前缀,先从3个前缀字母开始
select count(*) as cnt,left(city,3) as pref from sakia.city_demo group by pref order by cnt desc limit 10;
//每个前缀都比原来的城市出现的次数更多,因此唯一的前缀比唯一的城市要少的多,然后我们增加前缀长度,
//直到这个前缀的选择性接近完整列的选择性,经过试验后发现前缀长度为7的比较适合
select count(*) as cnt ,left(city,7) as pref from sakia.city_demo group by pref order by cnt desc limit 10;
//创建一个前缀索引
alter table sakia.city_demo and key (city(7));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值