Schema与数据类型优化

关于整数类型:

1.整数类型都有可选的UNSIGNED,表示不允许负值。
2.为整数类型指定显示宽度是没有意义的,只会控制客户端显示字符的个数。

关于实数类型:

1.不精确类型:FLOAT,DOUBLE; 精确类型:DECIMAL
2.CPU不支持对DECIMAL进行直接运算,可以直接对浮点进行运算;同时,DECIMAL会占用更多的空间,MySQL将数字打包
  保存到一个二进制字符串中,每4个字节存储9个数字。
3.可以使用BIGINT代替DECIMAL,放大对应倍数即可。

CHAR类型的优点:

1.定长的数据
2.很短的数据,因为VARCHAR还需要1 or 2个字节记录字符串的长度;比如说Y或者N
3.经常更新的列可以用CHAR,因为VARCHAR会产生碎片

日期和时间类型:

1.DATETIME可以表示到9999年,使用8个字节。
2.TIMESTAMP只能表示到2038年,使用4个字节,且与时区有关,推荐使用TIMESTAMP。
3.TIMESTAMP的行为规则比较复杂,建议使用SHOW CREATE TABLE查看。

计数器表:

1.考虑到高并发问题的计数器表:(ROUND函数的使用,可以删除)
CREATE TABLE hit_counter(
	slot tinyint unsigned not null primary key,
	cnt int unsigned not null
)ENGINE=InnoDB;
--需要预先在表里插入100行数据
UPDATE hit_counter SET cnt = cnt + 1 WHERE slot=round(rand()*100);
--统计结果
SELECT SUM(cnt) FROM hit_counter;

2.每隔一段时间需要开始一个新的计数器,同时不能预先生成行。
CREATE TABLE daily_hit_counter(
	day date not null,
	slot tinyint unsigned not null,
	cnt int unsigned not null,
	primary key(day, slot)
)ENGINE=InnoDB;

--使用ON DUPLICATE KEY
INSERT INTO daily_hit_counter(day,slot,cnt)
	VALUES(CURRENT_DATE, ROUND(RAND()*100),1) ON DUPLICATE KEY UPDATE cnt=cnt+1;

3.如果上述ROUND进行约束,那么计数器表中会产生大量的行;所以需要一个周期任务合并所有的结果到0号槽位。

UPDATE daily_hit_counter as c
	INNER JOIN (
		SELECT day, sum(cnt) as cnt, min(slot) as mslot
		FROM daily_hit_counter
		GROUP BY day
	) as x using(day)
SET c.cnt = IF(c.slot=x.mslot, x.cnt, 0), c.slot = IF(c.slot=x.mslot, 0, c.slot);

--然后删除其余的槽位
DELETE FROM daily_hit_counter WHERE slot <> 0 AND cnt=0;

ALTER TABLE问题:

1.MySQL中大部分修改表的操作都是,创建一个空表,然后从旧表中查出所有数据插入新表。
2.如果要修改表的默认值,可以使用ALTER TABLE COLUMN,这个语句会直接修改.frm文件而不涉及数据。
3.ALTER TABLE允许使用ALTER COLUMN,MODIFY COLUMN,和CHANGE COLUMN语句修改列,这三种操作不同
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值