关于整数类型:
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语句修改列,这三种操作不同