k
v
是一个唯一的字符串(varchar 32),insert into
select v from TABLE where k = "${k}"
也是一个字符串(varchar 50),
我只会做这些查询:
{{1}}
我该如何编写我的create table sql?
喜欢mysql中的分区?我应该用吗?例如,我应该使用myisam还是innodb?
我有很多读取,很少插入,所以行级锁定InnoDB可能适合吗?
答案 0 :(得分:1)
这是一个测试问题吗?假设我们不允许NULL值,并且我们不允许重复,我会选择索引组织表:
CREATE TABLE mytable
( k VARCHAR(32) NOT NULL COMMENT 'pk (cluster key), ...'
, v VARCHAR(50) NOT NULL COMMENT 'pk (cluster key), ...'
, PRIMARY KEY (k,v)
) ENGINE=InnoDB
最重要的是群集密钥,由于WHERE子句中的等式谓词,因此'k'是前导列。
如果'k'保证是唯一的,那么它就可以作为PRIMARY KEY。
CREATE TABLE mytable
( k VARCHAR(32) NOT NULL COMMENT 'pk (cluster key), ...'
, v VARCHAR(50) NOT NULL COMMENT '...'
, PRIMARY KEY (k)
) ENGINE=InnoDB
这将阻止INSERT创建具有重复值'k'的行。
在最坏的情况下,如果关于可空性和唯一性的假设无效,那么在提供群集密钥方面我们处于一个受损的世界。我们可以让InnoDB使用内部标识符作为集群密钥,只需为我们的查询创建覆盖索引,由于内部标识符的开销和单独的索引,需要大约两倍的空间:
CREATE TABLE mytable
( k VARCHAR(32) COMMENT ''
, v VARCHAR(50) COMMENT ''
, KEY mytable_IX1 (k,v)
) ENGINE=InnoDB
这不是那么有效,但它确实允许重复和NULL。同样,我们想要一个前导列为k
的索引(由于WHERE子句中的等式谓词),还包括v
(使其成为覆盖索引),因此可以满足SELECT查询从索引页面,无需在基础数据表中查找页面。
MySQL支持InnoDB以外的存储引擎。这是我们最好的猜测,没有关于群集,复制等的任何其他规范。
假设innodb_file_per_table
已启用,我会考虑进行分区。这不会在查询性能方面发挥作用,但这可以提高表的可管理性,例如,如果我们想要或需要重新组织
PARTITION BY RANGE (k)
( PARTITION ke VALUES LESS THAN ('e')
, PARTITION ki VALUES LESS THAN ('i')
, PARTITION ko VALUES LESS THAN ('o')
, PARTITION ku VALUES LESS THAN ('u')
, PARTITION kz VALUES LESS THAN ('z')
, PARTITION px VALUES LESS MAXVALUE
)
然后我们可以一次重新组织一个分区:
ALTER TABLE mytable REBUILD PARTITION ko;