【问题标题】:Pivot table design with multi-column PRIMARY key MySQL使用多列主键 MySQL 的数据透视表设计
【发布时间】:2011-09-25 07:58:27
【问题描述】:

任何人都可以立即看到下面架构中的问题或瓶颈吗?读取是 90% 的操作,但我想知道我是否在写入的任何地方都在开枪。

命题

每个对象(另一个表中的行)都可以与其他对象相关联。每个关系对只能有一个记录(对是方向敏感的,所以XY 可以YX 共存)。

+-------+---------------------+------+-----+---------+----------------+
| Field | Type                | Null | Key | Default | Extra          |
+-------+---------------------+------+-----+---------+----------------+
| a_id  | bigint(20) unsigned | NO   | PRI | NULL    |                |
| b_id  | bigint(20) unsigned | NO   | PRI | NULL    |                | 
+-------+---------------------+------+-----+---------+----------------+

一个典型的请求是获取所有相关对象(对于给定对象A):

SELECT * FROM objects INNER JOIN relations ON id = b_id WHERE a_id = A

使用 UI 中的简单复选框数组管理关系。为了保存关系,我会计算当前集合中选中/未选中之间的差异(对象将在 UI 中分页),然后相应地插入/删除;

DELETE FROM relations WHERE a_id = A AND b_id IN(B,C)

# if these relations already exist, will fail silently
INSERT IGNORE INTO relations (a_id, b_id) VALUES (A,D), (A,E)

可能还需要查询反向关系,只使用b_id 进行选择 - 因为它不在索引的左侧,它会被使用吗?如果没有,在其上添加单独的索引是否会导致大量写入开销?

【问题讨论】:

  • 表是什么引擎?您可能希望在单个事务中执行 DELETE / INSERT

标签: mysql database-design indexing


【解决方案1】:

b_id 上添加第二个索引的优势将超过写入的任何开销,因为没有索引,它需要进行全表扫描以按b_id 过滤。

至于仅在b_idb_id, a_id 上建立索引取决于表引擎,因为InnoDB 将主键存储在二级索引中,但MyISAM 没有。

【讨论】:

  • 原谅我的无知,但是对于 InnoDB,b_id 就足够了吗?
  • 说我必须使用 MyISAM(系统是分布式的,InnoDB 无法保证) - 添加b_id, a_id 索引会阻碍 InnoDB 吗?即为一个/或妥协?
猜你喜欢
  • 1970-01-01
  • 2023-04-08
  • 2021-02-12
  • 2018-07-06
  • 1970-01-01
  • 2015-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多