我不知道如何将我的分层数据存储在我的innoDB表中。
我读了很多关于在每一行中存储parent_id
的方法的缺点的文章。但现在的问题是,我有一个非常大的数据库(大约5000万行)。层次结构大多不是很深(3-6级)。
许多网站建议将“嵌套集合模型”作为父id存储方法的更好替代方案。但总会有一些变化(UPDATE
、INSERT
等)网站的用户和我的表格的大小,这将花费太多的时间(因为在“嵌套集模型”中的更改具有非常低的性能)。
所以我的问题是:如何使用许多update
/insert
命令有效地存储大型分层数据?(阻塞整个表也不是一个选项-> innoDB- table )
发布于 2013-01-02 05:52:25
当您需要频繁地更新树时,嵌套集合的设计无疑是困难的。最终,您必须对树的大部分进行重新编号。
缓解这一问题的一个建议是使用浮点数而不是整数。如果您在树中插入一个新节点,在新节点的父节点的嵌套集合编号之间找到一些浮点数是相对容易的。您可能最终会达到浮点数的精度极限,但由于您的树不是很深,这种情况在很长一段时间内不会发生。
我写过的另一种技术,我称之为闭合表。这种存储层次结构的方法使得在大树中插入/更新/删除节点变得更加容易,而不需要更新大量的树。而且您仍然可以在单个非递归SQL查询中查询整个树或任何子树。
要了解有关闭合表的更多信息,请参阅:
请回复您的评论:
邻接列表很简单,具有最小的冗余,并且它支持嵌套集合所不支持的FK关系。如果您使用recursive queries,邻接表支持查询任意深度的整个树。但是MySQL不支持递归查询。
如果您只需要查询直接的父子关系(即一个深度级别),或者只查询固定深度的树,那么邻接表就可以了。
发布于 2013-01-02 05:50:38
对于分层数据,我喜欢保持层次结构的分离。例如,如果我们处理的是员工层次结构,我通常会这样做-
create table employee (
id serial primary key,
name varchar(50));
create table roster (
id serial primary key,
employee_id int references employee (id),
supervisor_id int references employee (id));
通过将row_date
或start_date
和stop_date
字段添加到roster
表中,可以对其进行扩展以提供历史层次结构。
确保在适用的情况下应用了unique
约束和触发器,以强制执行业务规则。
https://stackoverflow.com/questions/14114280
复制相似问题