我非常喜欢数据库设计以及语义管理数据的整个概念以及随之而来的所有逻辑.
然而,我对数据库的知识水平(我猜)非常基础 - 我可以使用ER图,连接表,处理多对多,一对多等来正确建模数据关系.我有经验当谈到编程时,我认为我的数据库知识就像了解面向对象编程的基础知识,即如何建模汽车类,继承车辆类,包含车轮对象等等.
现在我想进一步了解关系数据库,以便我可以自信地向雇主说我可以在专业水平上处理这个问题.
我现在所能处理的可能就是我个人网站后端的电影数据库,如果我是亚马逊并且不得不存储数百万部电影,这可能会崩溃.那么可扩展性的主题是什么?我确信在数据库设计中有一个非常"标准"的主题/概念阵列,如果你打算在专业级别上使用数据库,你必须理解并能够应用于现实生活中.
所以,如果该领域的任何数据库专家可以命名某些领域,概念,案例研究或任何有利于研究以获得真正擅长数据库的东西,我将非常感激.我相信这里潜藏着巨大的科学,我想要它.
提前致谢!
我有一个使用Closure Table方法保存分层数据的MySQL数据库.一个简单的示例数据库创建脚本遵循该问题.我目前的问题是如何以正确的顺序从数据库中提取数据?我目前正在使用以下select语句.
SELECT `TreeData`.`iD`, `TreeData`.`subsectionOf`,
CONCAT(REPEAT('-', `TreePaths`.`len`),`TreeData`.`name`),
`TreePaths`.`len`,`TreePaths`.`ancestor`,`TreePaths`.`descendant`
FROM `TreeData`
LEFT JOIN `TreePaths` ON `TreeData`.`iD` = `TreePaths`.`descendant`
WHERE `TreePaths`.`ancestor` = 1
ORDER BY `TreeData`.`subsectionOrder`
Run Code Online (Sandbox Code Playgroud)
它会提取正确的信息,但输入顺序不正确.
示例数据库使用示例数据创建脚本.
-- Simple Sample
SET FOREIGN_KEY_CHECKS=0;
DROP TRIGGER IF EXISTS Tree_Insert;
DROP TRIGGER IF EXISTS Tree_Update;
DROP TABLE IF EXISTS TreePaths;
DROP TABLE IF EXISTS TreeData;
SET FOREIGN_KEY_CHECKS=1;
CREATE TABLE `TreeData` (
`iD` INT NOT NULL, -- PK
`subsectionOf` INT, -- Parent ID & FK
`subsectionOrder` INT, -- Oder of Subsections
`name` NVARCHAR(500) NOT NULL, …Run Code Online (Sandbox Code Playgroud) 我有一张桌子
create table site
(
site_Id int(5),
parent_Id int(5),
site_desc varchar2(100)
);
Run Code Online (Sandbox Code Playgroud)
领域的意义:
要求是,如果我有一个site_id作为输入,我需要在网站下面标记所有ID.例如:
A
/ \
B C
/ | \ /\
D E F G H
/\
I J
Run Code Online (Sandbox Code Playgroud)
所有节点都是site_Id.
该表包含如下数据:
Site_id | Parent_ID | site_desc
_________|____________|___________
A | -1 |
B | A |
C | A |
D | B |
E | B |
F | B |
I | D |
J | D |
Run Code Online (Sandbox Code Playgroud)
......
A是B和C的父级,依此类推.
如果B是给定的输入,那么查询需要获取D,E,I,F,J
它目前通过循环中的多个查询来实现,但我想在最少数量的查询中实现这一点.
我目前正在做的是::
投票 …
我有一个文件夹表,以id,parent_id关系与自身连接:
CREATE TABLE folders (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
title nvarchar(255) NOT NULL,
parent_id int(10) unsigned DEFAULT NULL,
PRIMARY KEY (id)
);
INSERT INTO folders(id, title, parent_id) VALUES(1, 'root', null);
INSERT INTO folders(id, title, parent_id) values(2, 'one', 1);
INSERT INTO folders(id, title, parent_id) values(3, 'target', 2);
INSERT INTO folders(id, title, parent_id) values(4, 'child one', 3);
INSERT INTO folders(id, title, parent_id) values(5, 'child two', 3);
INSERT INTO folders(id, title, parent_id) values(6, 'root 2', null);
INSERT …Run Code Online (Sandbox Code Playgroud) 我知道有两种方法:邻接列表和嵌套树.据说由于大量查询,邻接列表在遍历上使用会很慢.但我不知道这方面的任何实际数字.我正在制作的网站将有200页.遍历生成(例如)站点地图需要花费超过0.3秒的时间吗?
使用LAMP堆栈在MySQL(innoDB)上运行.
如果可能的话,我更愿意实现邻接,因为设计更简单.
谢谢.
有一段时间我一直在努力解决如何最好地处理SQL中的层次结构.由于邻接列表的限制和MPTT /嵌套集的复杂性而感到沮丧,我开始考虑简单地存储密钥路径,作为一个简单的node_key/node_key/...字符串.我决定编译这三种技术的优点和缺点:
除了一个用例之外,存储的路径技术使用与每个用例中的其他技术相同或更少的调用.通过这种分析,存储路径是明显的赢家.更不用说,它实现起来要简单得多,人类可读等等.
所以问题是,不应该将存储路径视为比MPTT更强大的技术吗?为什么存储路径不是更常用的技术,为什么不在给定实例中使用它们而不是MPTT?
另外,如果您认为此分析不完整,请告诉我们.
这里至少有两件事MPTT可以开箱即用,存储的路径解决方案不会:
我有一个MySQL表,表示树GUI组件的数据,这是我的表的结构:
treeTable (
id INT NOT NULL PRIMARY KEY,
parentId INT,
name VARCHAR(255)
);
Run Code Online (Sandbox Code Playgroud)
parentId 是一个自引用外键.
现在我想编写一个存储过程,它获取一个节点id并返回一个包含该节点及其所有父节点的结果集.
例如,假设我的表已填充此数据:
1, null, 'root'
2, 1 , 'level_1'
3, 2 , 'level_2'
Run Code Online (Sandbox Code Playgroud)
现在我想获取节点3(节点1和2)的所有父节点并返回包含所有树记录的结果集.有人能帮帮我吗?
我有一个数据库,其中包含使用邻接列表模型存储的类别层次结构.
层次结构深度为3级(不包括假想的根节点),包含大约1700个节点.第二级和第三级的节点可以有多个父节点.另外一个表用于多对多关系,如下所示:
CREATE TABLE dbo.Category(
id int IDENTITY(1,1) NOT NULL,
name varchar(255) NOT NULL,
)
CREATE TABLE dbo.CategoryHierarchy(
relId int IDENTITY(1,1) NOT NULL,
catId int NOT NULL,
parentId int NOT NULL,
)
Run Code Online (Sandbox Code Playgroud)
如果我转向使用传递闭包表方法(为了数据完整性等)是否有一个相对容易的查询,我可以执行,将生成闭包表的值?(使用SQL Server 2005)
我查看文章和演示文稿,例如Bill Karwin的分层数据模型,但只有单个节点的插入查询,我需要永远创建这样的树.
谢谢.
编辑:
CategoryHierarchy表中的RelID纯粹是为了主键,它与Category表的节点ID无关.
还有闭包表,我的意思是这样一个表:
CREATE TABLE ClosureTable (
ancestor int NOT NULL,
descendant int NOT NULL,
[length] int NOT NULL,
)
Run Code Online (Sandbox Code Playgroud)
前两列是复合主键,并且是Category.id的单独外键.
我正在开发一个系统,需要允许用户被分组.这些组可以由系统中的其他特权用户自由创建,编辑和删除.那部分很容易; 只需创建一个group_users将用户链接到组的表.(如果你是规范化的坚持者,那么你可以创建一个group只列出组的group_users表,然后有一个表将它们链接在一起 - 这也很好)
这是它变得棘手的地方.客户端希望组还包含任意深度和任意重叠的组(组可以在多个组中,组可以包含多个组).这很容易存储(使用group_groups表),但如果没有像Oracle的CONNECT BY这样的排序扩展,很难查询.
这个递归层次结构也需要追溯 - 意味着如果组A包含组B,组B被修改,那么组A也将被修改 - 所以我不能作弊并且只是扁平化结构.如果你不相信我,它不能简单地被夷为平地,请考虑这种情况.你有一个名为"酷人"的小组,其中包含用户1和2.有人创建了一个名为"真正很酷的人"的小组,其中包含用户3并包含"酷人"组.当我查询"真的很酷的人"时,我应该得出结论,用户1,2和3都在群组中.现在说有人决定用户2不再是一个很酷的人,并从"酷人"中删除用户2.在那个时间点之后,"真正很酷的人"只包含用户1和3.如果我最初将结构弄平,当我将他从"酷人"中删除时,我不知道将用户2从"真正的酷人"中删除".
因此,在这种情况下,一个微不足道的扁平化将不起作用.我考虑过的其他选择:
group_users_flattened,但也保持一张group_groups桌子.为group_users_flattenedINSERT/UPDATE/DELETE 创建一个触发器,该触发器将转到该group_groups表,查找包含该组的所有组,并动态地进行相应的更改group_users_flattened.
还有其他我未考虑过的想法吗?
我需要创建能够将平面对象转换为递归对象的函数.这是我的例子:我有平面阵列:
var flatArray = [
{
Description: "G",
guid: "c8e63b35",
parent: null,
},
{
Description: "Z",
guid: "b1113b35",
parent: "c8e63b35",
},
{
Description: "F",
guid: "d2cc2233",
parent: "b1113b35",
},
{
Description: "L",
guid: "a24a3b1a",
parent: null,
},
{
Description: "K",
guid: "cd3b11caa",
parent: "a24a3b1a",
},
]
Run Code Online (Sandbox Code Playgroud)
结果应该是:
recursiveArray = [
{
Description: "G",
guid: "c8e63b35",
parent: null,
Children: [
{
Description: "Z",
guid: "b1113b35",
parent: "c8e63b35",
Children: [
{
Description: "F",
guid: "d2cc2233",
parent: "b1113b35",
}
]
},
]
}, …Run Code Online (Sandbox Code Playgroud) mysql ×6
sql ×5
algorithm ×2
database ×2
hierarchical ×1
hierarchy ×1
javascript ×1
mptt ×1
php ×1
recursion ×1
sql-server ×1
storage ×1
tree ×1