【发布时间】:2023-03-25 03:04:01
【问题描述】:
我在为我们的系统设计表架构时遇到了一个问题。
情况如下:
我们的系统有很多项目(超过 2000 万个),每个项目都有一个唯一的 id,但每个项目可以有很多记录。例如,对于 id 为 1 的项目,大约有 5000 条记录,每条记录有 20 多个属性。需要通过其 id 和一个或多个属性的状态来标识,以便在
select、update或delete中使用。我要使用innodb
但是问题是在使用innodb的时候,必须要有cluster index。
由于上述情况,它似乎必须找到一个集群索引,所以我只能使用 auto_increment int 作为键
目前的设计如下:
create table record (
item_key int(10) unsigned NOT NULL AUTO_INCREMENT,
item_id int(10) unsigned NOT NULL,
attribute_1 char(32) NOT NULL,
attribute_2 int(10) unsigned NOT NULL,
.
.
.
.
.
attribute_20 int(10) unsigned NOT NULL,
PRIMARY KEY (`item_key`),
KEY `iattribute_1` (`item_id`,`attribute_1`),
KEY `iattribute_2` (`item_id`,`attribute_2`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1
sql语句:
select * from records
where item_id=1 and attribute_1='a1' and attribute_2 between 10 and 1000;
update 和 delete 语句类似。
我不认为这是一个好的设计,但我想不出别的;欢迎所有建议。
对不起,如果我没有把问题说清楚。
我想要访问(选择、更新、删除、插入)的是记录,而不是项目。 项目有自己的属性,但在上面的描述中,我提到的属性是属于记录的。
每个项目可以有很多记录,比如项目 1 有大约 5000 条记录。
每条记录有42个属性,其中一些可以为NULL,每条记录都有一个唯一的id,这个id在不同的item中是唯一的,但是这个id是字符串而不是数字
-
我想以这种方式访问记录:
A.我只会在一次或一次查询中获取(或更新或删除)属于一个特定项目的记录
B.我将获取或更新查询中所有属性或某些特定属性的值
C.查询条件中的属性可能和我想要的属性不一样。
所以可能会有一些 SQL 语句,例如:
Select attribute_1, attribute_N from record_table_1 where item_id=1 and attribute_K='some value' and attribute_M between 10 and 100
而我认为原设计不好的原因有:
我不能选择一个属性或记录id作为主键,因为它没有用,在每个查询中,我必须分配项目id和一些属性作为查询条件(比如“哪里item_id=1 and attribute_1='value1' and attribte_2 between 2 and 3),所以我只能用一个auto_increment int number作为主键。这样的结果就是每次查询都要扫描两棵b-tree,看起来比如二级索引的扫描是无效的。
复合键似乎也没什么用,因为查询的条件可能因许多属性而异。
按照原来的设计,我好像加了很多索引来满足不同的查询,不然就得处理全表扫描的问题,但是显然索引太多不利于更新、删除、插入操作。
【问题讨论】: