我正在编写一个数据仓库,使用MySQL作为后端。我需要根据两个整数ID和一个名称字符串对表进行分区。我已阅读(部分)有关分区的mySQL文档,在这种情况下,最合适的分区方案似乎是HASH或KEY分区。
我已经选择了KEY分区,因为我(小伙子)并不想负责为我的字段提供“无冲突”散列算法 - 相反,我依靠MySQL散列来生成散列所需的密钥
我在下面列出了一个表格架构的片段,我希望根据以下字段的COMPOSITE进行分区:
school id,course_id,ssname(student surname)。
顺便说一句,在有人指出这不是存储学校相关信息的最佳方式之前,我必须指出我只是将下面的案例用作我想要建模的类比。My Current CREATE TABLE语句如下所示:
CREATE TABLE foobar (
id int UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
school_id int UNSIGNED NOT NULL,
course_id int UNSIGNED NOT NULL,
ssname varchar(64) NOT NULL,
/* some other fields */
FOREIGN KEY (school_id) REFERENCES school(id) ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY (course_id) REFERENCES course(id) ON DELETE RESTRICT ON UPDATE CASCADE,
INDEX idx_fb_si (school_id),
INDEX idx_fb_ci (course_id),
CONSTRAINT UNIQUE INDEX idx_fb_scs (school_id,course_id,ssname(16))
) ENGINE=innodb;
我想知道如何修改上面的语句,以便使用我在本问题开头提到的三个字段(即 - school_id,course_id和学生姓氏的起始字母)对表进行分区。
我想问的另一个问题是:
在'edge'情况下会发生什么,例如,如果我尝试插入包含有效* school_id,course_id或surname的记录 - 没有底层分区表文件 - mySQL会自动创建底层文件。
例证。我有以下学校:纽约Kindergaten,贝尔法斯特小学和以下课程:信息维度中的李代数,纠缠实体
还假设我有以下学生(姓氏):布什,布莱尔,侯赛因
当我添加一所新学校(或课程,或学生)时,我可以将它们插入到foobar表中(实际上,我想不出为什么不这样做)。我问的原因是我预测会增加更多的学校和课程等,这意味着mySQL必须在幕后创建额外的表格(因为哈希会产生新的密钥)。
如果在此领域有经验的人能够确认(最好有支持他们断言的链接),我将不胜感激,我的理解(即如果我将新的学校,课程或学生添加到数据库中,则无需人工管理),正确的。
我不知道我的第二个问题是否形成得很好(清楚)。如果没有,我将很乐意进一步澄清。
* VALID - 有效,我的意思是它在不破坏参照完整性方面是有效的。
答案 0 :(得分:2)
我怀疑分区是否像你想象的那样有用。也就是说,你要求的还有其他一些问题(注意:这个答案的全部内容适用于MySQL 5;版本6可能有所不同):
school_id
,course_id
和ssname
不属于主键。ssname
将不是整数值。幸运的是,无冲突散列是您不必担心的一件事,因为分区将导致冲突(否则,您在每个分区中只有一行)。如果您可以忽略上述问题以及limitations on functions used in partitioning expressions,则可以使用以下命令创建HASH分区:
CREATE TABLE foobar (
...
) ENGINE=innodb
PARTITION BY HASH (school_id + course_id + ORD(ssname))
PARTITIONS 2
;
应该做些什么:
CREATE TABLE foobar (
id int UNSIGNED NOT NULL AUTO_INCREMENT,
school_id int UNSIGNED NOT NULL,
course_id int UNSIGNED NOT NULL,
ssname varchar(64) NOT NULL,
/* some other fields */
PRIMARY KEY (id, school_id, course_id),
INDEX idx_fb_si (school_id),
INDEX idx_fb_ci (course_id),
CONSTRAINT UNIQUE INDEX idx_fb_scs (school_id,course_id,ssname)
) ENGINE=innodb
PARTITION BY HASH (school_id + course_id)
PARTITIONS 2
;
或:
CREATE TABLE foobar (
id int UNSIGNED NOT NULL AUTO_INCREMENT,
school_id int UNSIGNED NOT NULL,
course_id int UNSIGNED NOT NULL,
ssname varchar(64) NOT NULL,
/* some other fields */
PRIMARY KEY (id, school_id, course_id, ssname),
INDEX idx_fb_si (school_id),
INDEX idx_fb_ci (course_id),
CONSTRAINT UNIQUE INDEX idx_fb_scs (school_id,course_id,ssname)
) ENGINE=innodb
PARTITION BY KEY (school_id, course_id, ssname)
PARTITIONS 2
;
对于存储表的文件,MySOL会创建它们,虽然它可以在您定义表时而不是在将行插入其中时执行。您无需担心MySQL如何管理文件。请记住,当您通过PARTITIONS *n*
子句创建表时,会定义有限数量的分区。