精华内容
下载资源
问答
  • ①关系型数据库的表结构 例如有一个用户表user_info,有字段:id、name、tel,表名和字段需要在建表时指定 create table user_info ( id 类型, ...数据表是二维结构,行和列 添加字段不灵活 下面看一

    HBase表格结构

    HBase的表格中涉及到几个概念,用一个例子来解释,这一部分看了很多博客,其中HBase概念及表格设计解释得很通俗,可以看一下。

    HBase中一个可能的表格如下,包括:

    RowKey:行键,类似关系表中的主键,是用来表示唯一一行记录的主键,按字典序排列
    Column:列,类似关系表中的列,在下图中的列就是Gender,Age,Province,City
    ColumnFamily:列族,是列的集合,不同的列族存储在不同文件中,引入这个概念是因为HBase查询中,很多情况下不需要一行中所有的列
    Cell:单元格,由【RowKey、Column】确定的单元格,如下图中的Male,20…
    TimeStamp:数据修改时加入的时间戳,下图中作为单独一列,实际上这个值是存放在单元格中的,见下面的例子
    在这里插入图片描述
    实际:
    在这里插入图片描述
    表在HBase中的逻辑表示如下,一个单元格包含数据的若干个版本,是【时间戳:值】的列表
    在HBase中不同的列族存储在不同文件中,同一列族的数据在存储介质上连续
    比如上面的表,在HBase中存储大致如下:
    Mike - BasicInfo:Gender - T1:Male
    Mike - BasicInfo:Age - T1:20
    Mike - BasicInfo:Age - T3:21
    Amy - BasicInfo:Gender - T2:Female
    Amy - BasicInfo:Age - T2:18
    Mike - AddressInfo:Province - T1:GuangDong
    Mike - AddressInfo:City - T1:Guangzhou
    Amy - AddressInfo:Province - T2:GuangDong
    Amy - AddressInfo:City - T2:Shenzhen

    参考:https://blog.csdn.net/qq_36153312/article/details/90704549

    ①关系型数据库的表结构

    例如有一个用户表user_info,有字段:id、name、tel,表名和字段需要在建表时指定
    create table user_info (

    id 类型,
    
    name 类型,
    
    tel 类型
    

    )
    然后插入两条数据
    insert into user_info values(…)
    表结构如下:
    在这里插入图片描述
    以后再增加需求时,就需要继续新增字段。

    上面的内容主要说明的是:

    建表的方式,需提前指定表名和字段
    插入记录的方式,指定表名和各字段的值
    数据表是二维结构,行和列
    添加字段不灵活

    下面看一下HBase的处理方式

    ②HBase的表结构
    建表时要指定的是:表名、列族
    建表语句:create ‘user_info’, ‘base_info’, ‘ext_info’
    意思是新建一个表,名称是user_info,包含两个列族base_info和ext_info
    列族 是列的集合,一个列族中包含多个列
    这时的表结构:
    在这里插入图片描述
    row key 是行键,每一行的ID,这个字段是自动创建的,建表时不需要指定,也不需要创建

    插入一条用户数据:name为‘a’,tel为‘123’
    插入语句
    put ‘user_info’, ‘row1’, ‘base_info:name’, ‘a’
    put ‘user_info’, ‘row1’, ‘base_info:tel’, ‘123’
    意思是向user_info表中行健为row1的base_info列族中添加一项数据 name:a,接着又添加一项数据tel:123
    name和tel就是具体字段,属于base_info这个列族
    这时的表结构:
    在这里插入图片描述
    小结
    从上面建表、插入数据的过程可以看出 HBase 存储数据的特点了
    和关系数据库一样,也是使用行和列的结构
    建表时,定义的是表名和列族(字段的集合),而不是具体字段
    列族中可以包含任意个字段,字段名不需要预定义,每一行中同一列族中的字段也可以不一致
    多维结构,关系数据库的表是二维的,通过指行、列定位一个数据,HBase中需要通过 行健、列族名、字段名、版本号才能定位到具体数据
    插入数据时,一次插入一个字段的数据,不是像关系数据库那样一次插入多个字段

    语法

    下面给出一些语句仅供参考:
    创建user表,包含info、data两个列族
    create 'user', 'info1', 'data1'
    create 'user', {NAME => 'info', VERSIONS => '3'}
    
    向user表中插入信息,row key为rk0001,列族info中添加name列标示符,值为zhangsan
    put 'user', 'rk0001', 'info:name', 'zhangsan'
    
    向user表中插入信息,row key为rk0001,列族info中添加gender列标示符,值为female
    put 'user', 'rk0001', 'info:gender', 'female'
    
    向user表中插入信息,row key为rk0001,列族info中添加age列标示符,值为20
    put 'user', 'rk0001', 'info:age', 20
    
    向user表中插入信息,row key为rk0001,列族data中添加pic列标示符,值为picture
    put 'user', 'rk0001', 'data:pic', 'picture'
    
    获取user表中row key为rk0001的所有信息
    get 'user', 'rk0001'
    
    获取user表中row key为rk0001,info列族的所有信息
    get 'user', 'rk0001', 'info'
    
    获取user表中row key为rk0001,info列族的name、age列标示符的信息
    get 'user', 'rk0001', 'info:name', 'info:age'
    
    获取user表中row key为rk0001,info、data列族的信息
    get 'user', 'rk0001', 'info', 'data'
    get 'user', 'rk0001', {COLUMN => ['info', 'data']}
    get 'user', 'rk0001', {COLUMN => ['info:name', 'data:pic']}
    
    获取user表中row key为rk0001,列族为info,版本号最新5个的信息
    get 'people', 'rk0002', {COLUMN => 'info', VERSIONS => 2}
    get 'user', 'rk0001', {COLUMN => 'info:name', VERSIONS => 5}
    get 'user', 'rk0001', {COLUMN => 'info:name', VERSIONS => 5, TIMERANGE => [1392368783980, 1392380169184]}
    
    获取user表中row key为rk0001,cell的值为zhangsan的信息
    get 'people', 'rk0001', {FILTER => "ValueFilter(=, 'binary:图片')"}
    
    获取user表中row key为rk0001,列标示符中含有a的信息
    get 'people', 'rk0001', {FILTER => "(QualifierFilter(=,'substring:a'))"}
    put 'user', 'rk0002', 'info:name', 'fanbingbing'
    put 'user', 'rk0002', 'info:gender', 'female'
    put 'user', 'rk0002', 'info:nationality', '中国'
    get 'user', 'rk0002', {FILTER => "ValueFilter(=, 'binary:中国')"}
    
    查询user表中的所有信息
    scan 'user'
    
     
    
    查询user表中列族为info的信息
    scan 'people', {COLUMNS => 'info'}
    scan 'user', {COLUMNS => 'info', RAW => true, VERSIONS => 5}
    scan 'persion', {COLUMNS => 'info', RAW => true, VERSIONS => 3}
    
    查询user表中列族为info和data的信息
    scan 'user', {COLUMNS => ['info', 'data']}
    scan 'user', {COLUMNS => ['info:name', 'data:pic']}
    
    查询user表中列族为info、列标示符为name的信息
    scan 'user', {COLUMNS => 'info:name'}
    
     
    
    查询user表中列族为info、列标示符为name的信息,并且版本最新的5个
    scan 'user', {COLUMNS => 'info:name', VERSIONS => 5}
    
     
    
    查询user表中列族为info和data且列标示符中含有a字符的信息
    scan 'people', {COLUMNS => ['info', 'data'], FILTER => "(QualifierFilter(=,'substring:a'))"}
    
     
    
    查询user表中列族为info,rk范围是[rk0001, rk0003)的数据
    scan 'people', {COLUMNS => 'info', STARTROW => 'rk0001', ENDROW => 'rk0003'}
    
     
    
    查询user表中row key以rk字符开头的
    scan 'user',{FILTER=>"PrefixFilter('rk')"}
    
     
    
    查询user表中指定范围的数据
    scan 'user', {TIMERANGE => [1392368783980, 1392380169184]}
    
     
    
    禁用表
    disable 'user' 将数据表设置为失效
    
     
    
    删除表
    drop 't_user' 删除数据表 删除前必须使其失效
    
     
    
    启用表
    
    enable 't_user' 将数据表设置为有效
    
     
    
    查看表结构
    
    desc 't_user' 查看数据表结构
    
     
    
    删除user表row key为rk0001,列标示符为info:name的数据
    
    delete 'people', 'rk0001', 'info:name'
    
    删除user表row key为rk0001,列标示符为info:name,timestamp为1392383705316的数据
    
    delete 'user', 'rk0001', 'info:name', 1392383705316
    
     
    
    清空user表中的数据
    
    truncate 'people'
    

    参考:https://www.cnblogs.com/supiaopiao/p/7270592.html

    HBase表特点

    数据规模大,单表可容纳数十亿行,上百万列。
    无模式,不像关系型数据库有严格的Scheme,每行可以有任意多的列,列可以动态增加,不同行可以有不同的列,列的类型没有限制。
    稀疏,值为空的列不占存储空间,表可以非常稀疏,但实际存储时,能进行压缩。
    面向列族,面向列族的存储和权限控制,支持列族独立查询。
    数据多版本,利用时间戳来标识版本
    数据无类型,所有数据以字节数据形式存储

    展开全文
  • 二维表

    2013-04-25 21:39:53
    在关系模型中,数据结构表示为一个二维表,一个关系就是一个二维表(但不是任意一个二维表都能表示一个关系),二维表名就是关系名。表中第一行通常称为属性名,表中每一个元组和属性都是不可再分,且元组...
    在关系模型中,数据结构表示为一个二维表,一个关系就是一个二维表(但不是任意一个二维表都能表示一个关系),二维表名就是关系名。表中的第一行通常称为属性名,表中的每一个元组和属性都是不可再分的,且元组的次序是无关紧要的。
      常用的关系术语如下:
      记录 二维表中每一行称为一个记录,或称为一个元组。
      字段 二维表中每一列称为一个字段,或称为一个属性。
      域 即属性的取值范围。 
      关键字 在一个关系中有这样一个或几个字段,它(们)的值可以唯一地标识一条记录,称之为关键字(Key)。例如,在学生关系中,学号就是关键字。
      关系模式 对关系的描述称为关系模式,其格式为:
      关系名(属性名1,属性名2,…,属性名n)
      一个关系模式对应一个关系的结构,它是命名的属性集合。
    展开全文
  • 关系模型的数据结构 关系模型源于数学 它用二维表来组织数据 而这个二维表在关系数据库中称为 关系 关系数据库是表的集合 用关系表示实体以及实体间的联系的模型 称为关系模型 下面我们来看看关系 模型中的基本术语 ...
  • 层次数据结构的数据表设计存储树形结构数据是一个常见的问题,同时也有多种解决方案。这里介绍三种树形结构的设计方案:邻接表模型基于路径和层级的设计基于左右值编码的设计(MPT)这里以一个在线食品店作为...

    层次数据结构的数据表设计

    存储树形结构数据是一个常见的问题,同时也有多种解决方案。

    这里介绍三种树形结构的表设计方案:邻接表模型

    基于路径和层级的表设计

    基于左右值编码的表设计(MPT)

    这里以一个在线食品店作为例子,食品通过类别、颜色和品种组织食品。

    示例如下:

    b8d2beb739f7f15fe2eb4100fa6d7a7f.png

    一、邻接表模型

    最简单的方法就是使用邻接表模型或者叫做递归模型。通过显示地描述某一节点的父节点,从而能够建立二维的关系表,你只需要一个简单的函数去迭代查询即可获取你的数据。

    示例如下:

    93b6dae5eb7286cd4bbabbb91ac72e8d.png

    优点:设计简单

    实现容易

    直观

    缺点:由于是递归模型CRUD操作低效

    二、基于路径和层级的表设计

    在一的基础上加上一个 level 字段来表示当前节点到根节点的距离和一个 key 字段来表示搜索路径。Node_id 主键

    Name 名字

    Parent_id 父节点的id

    key 搜索路径

    level 表示当前节点到根节点的距离或者层级

    示例如下:

    fa54df00a170e4863ce9fe8d7b7bc26a.png

    两种需求查询解决方案如下:查找d的所有子孙节点:select * from table_name where key like "${d.key}-${d.id}-%"

    查找某个节点的所有子节点:select * from table_name where key like "${d.key}-${d.id}-%" and level=${d.level}+1

    此设计结构简单,利用key和level两个辅助字段可以完成查询操作比一更加高效,而且维护这两个字段成本很低。

    三、基于左右值编码的表设计(MPT)

    为了避免对于树形结构查询时的“递归”过程,基于Tree的前序遍历设计一种全新的无递归查询、无限分组的左右值编码方案,来保存该树的数据。

    dce3d9405bc5074f167143646f6d56d2.png

    如下图所示, 从根节点Food左侧开始,标记为1,并沿前序遍历的方向,依次在遍历的路径上标注数字,最后我们回到了根节点Food,并在右边写上了18。

    注:lft 和 rgt 分别对应 DFS 的发现时间 d 和完成时间相同 f

    55686f0972ff995eadce460e504a7a44.png

    如果我们需要查询Fruit的后续节点,只需找出所有左值大于2,并且右值小于11的节点即可。

    1. 获取某节点的子孙节点

    返回某节点子孙节点的前序遍历列表,以Fruit为例:

    SQL: SELECT* FROM Tree WHERE Lft BETWEEN 2 AND 11 ORDER BY Lft ASC

    查询结果如下:

    e3a57f7e803ed5abac20f0945543ea04.png

    那么某个节点到底有多少的子孙节点呢?

    通过该节点的左、右值我们可以将其子孙节点圈进来,则子孙总数 = (右值 – 左值– 1) / 2,以Fruit为例,其子孙总数为:(11 –2 – 1) / 2 = 4。

    同时,为了更为直观地展现树形结构,我们需要知道节点在树中所处的层次,通过左、右值的SQL查询即可实现。以Fruit为例:SELECT COUNT(*) FROM Tree WHERE Lft <= 2 AND Rgt >=11。为了方便描述,我们可以为Tree建立一个视图,添加一个层次数列,该列数值可以写一个自定义函数来计算,函数定义如下:CREATE FUNCTION dbo.CountLayer

    (

    @node_id int

    )

    RETURNS int

    AS

    begin

    declare @result int

    set @result = 0

    declare @lft int

    declare @rgt int

    if exists(select Node_id from Tree where Node_id = @node_id)

    begin

    select @lft = Lft, @rgt = Rgt from Tree where node_id = @node_id

    select @result = count(*) from Tree where Lft <= @lft and Rgt >= @rgt

    end

    return @result

    end

    GO

    基于层次计算函数,我们创建一个视图,添加了新的记录节点层次的数列:CREATE VIEW dbo.TreeView

    AS

    SELECT Node_id, Name, Lft, Rgt, dbo.CountLayer(Node_id) AS Layer FROM dbo.Tree ORDER BY Lft

    GO

    创建存储过程,用于计算给定节点的所有子孙节点及相应的层次:CREATE PROCEDURE [dbo].[GetChildrenNodeList]

    (

    @node_id int

    )

    AS

    declare @lft int

    declare @rgt int

    if exists(select Node_id from Tree where node_id = @node_id)

    begin

    select @lft = Lft, @rgt = Rgt from Tree where Node_id = @node_id

    select * from TreeView where Lft between @lft and @rgt order by Lft ASC

    end

    GO

    现在,我们使用上面的存储过程来计算节点Fruit所有子孙节点及对应层次,查询结果如下:

    b1af26dca36b7fb66a95ca84730209fa.png

    在进行树的查询遍历时,只需要进行2次数据库查询,消除了递归,再加上查询条件都是数字的比较,查询的效率是极高的,随着树规模的不断扩大,基于左右值编码的设计方案将比传统的递归方案查询效率提高更多。

    2. 获取某节点的族谱路径

    假定我们要获得某节点的族谱路径,则根据左、右值分析只需要一条SQL语句即可完成。

    以Fruit为例:SELECT* FROM Tree WHERE Lft < 2 AND Rgt > 11 ORDER BY Lft ASC

    相对完整的存储过程如下:CREATE PROCEDURE [dbo].[GetParentNodePath]

    (

    @node_id int

    )

    AS

    declare @lft int

    declare @rgt int

    if exists(select Node_id from Tree where Node_id = @node_id)

    begin

    select @lft = Lft, @rgt = Rgt from Tree where Node_id = @node_id

    select * from TreeView where Lft < @lft and Rgt > @rgt order by Lft ASC

    end

    GO

    3. 为某节点添加子孙节点

    假定我们要在节点“Red”下添加一个新的子节点“Apple”,该树将变成如下图所示,其中红色节点为新增节点。

    cd19f84a60e00503cc43b0acc4d9e862.png

    相对完整的插入子节点的存储过程:CREATE PROCEDURE [dbo].[AddSubNode]

    (

    @node_id int,

    @node_name varchar(50)

    )

    AS

    declare @rgt int

    if exists(select Node_id from Tree where Node_id = @node_id)

    begin

    SET XACT_ABORT ON

    BEGIN TRANSCTION

    select @rgt = Rgt from Tree where Node_id = @node_id

    update Tree set Rgt = Rgt + 2 where Rgt >= @rgt

    update Tree set Lft = Lft + 2 where Lft >= @rgt

    insert into Tree(Name, Lft, Rgt) values(@node_name, @rgt, @rgt + 1)

    COMMIT TRANSACTION

    SET XACT_ABORT OFF

    end

    GO

    4. 删除某节点

    如果我们想要删除某个节点,会同时删除该节点的所有子孙节点,而这些被删除的节点的个数为:(被删除节点的右值 – 被删除节点的左值+ 1) / 2,而剩下的节点左、右值在大于被删除节点左、右值的情况下会进行调整。来看看树会发生什么变化,以Beef为例,删除效果如下图所示。

    90976539f959bfa949e7c9750d4108b8.png

    则我们可以构造出相应的存储过程:CREATE PROCEDURE [dbo].[DelNode]

    (

    @node_id int

    )

    AS

    declare @lft int

    declare @rgt int

    if exists(select Node_id from Tree where Node_id = @node_id)

    begin

    SET XACT_ABORT ON

    BEGIN TRANSCTION

    select @lft = Lft, @rgt = Rgt from Tree where Node_id = @node_id

    delete from Tree where Lft >= @lft and Rgt <= @rgt

    update Tree set Lft = Lft – (@rgt - @lft + 1) where Lft > @lft

    update Tree set Rgt = Rgt – (@rgt - @lft + 1) where Rgt > @rgt

    COMMIT TRANSACTION

    SET XACT_ABORT OFF

    end

    GO

    小结

    优点:消除了递归查询,实现了无限嵌套

    查询是基于整数的比较,效率很高

    缺点:节点的添加、删除及修改代价较大

    在基于数据库的一般应用中,查询的需求总要大于删除和修改,同时我们可以扩展MPT来实现更多的优化,例如:如果对层级需求较高,可以结合MPT和二中的方法来实现。

    Reference

    展开全文
  • 层次数据结构的数据表设计 存储树形结构数据是一个常见的问题,同时也有多种解决方案。 这里介绍三种树形结构的设计方案: 邻接表模型 基于路径和层级的设计 基于左右值编码的设计(MPT) 这里以一个在线...

    层次数据结构的数据表设计

    存储树形结构数据是一个常见的问题,同时也有多种解决方案。

    这里介绍三种树形结构的表设计方案:

    • 邻接表模型
    • 基于路径和层级的表设计
    • 基于左右值编码的表设计(MPT)

    这里以一个在线食品店作为例子,食品通过类别、颜色和品种组织食品。

    示例如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GYAHZQNJ-1612956420839)(assets\image-20210129145428312.png)]

    一、邻接表模型

    最简单的方法就是使用邻接表模型或者叫做递归模型。通过显示地描述某一节点的父节点,从而能够建立二维的关系表,你只需要一个简单的函数去迭代查询即可获取你的数据。

    示例如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CUR3I5zx-1612956420841)(assets\image-20210129145448067.png)]
    优点:

    • 设计简单
    • 实现容易
    • 直观

    缺点:

    • 由于是递归模型CRUD操作低效

    二、基于路径和层级的表设计

    在一的基础上加上一个 level 字段来表示当前节点到根节点的距离和一个 key 字段来表示搜索路径。

    1. Node_id 主键
    2. Name 名字
    3. Parent_id 父节点的id
    4. key 搜索路径
    5. level 表示当前节点到根节点的距离或者层级

    示例如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nJWbeWkX-1612956420845)(assets\image-20210129145544265.png)]
    两种需求查询解决方案如下:

    1. 查找d的所有子孙节点:select * from table_name where key like "${d.key}-${d.id}-%"
    2. 查找某个节点的所有子节点:select * from table_name where key like "${d.key}-${d.id}-%" and level=${d.level}+1

    此设计结构简单,利用key和level两个辅助字段可以完成查询操作比一更加高效,而且维护这两个字段成本很低。

    三、基于左右值编码的表设计(MPT)

    为了避免对于树形结构查询时的“递归”过程,基于Tree的前序遍历设计一种全新的无递归查询、无限分组的左右值编码方案,来保存该树的数据。
    在这里插入图片描述
    如下图所示, 从根节点Food左侧开始,标记为1,并沿前序遍历的方向,依次在遍历的路径上标注数字,最后我们回到了根节点Food,并在右边写上了18。

    注:lft 和 rgt 分别对应 DFS 的发现时间 d 和完成时间相同 f
    在这里插入图片描述
    如果我们需要查询Fruit的后续节点,只需找出所有左值大于2,并且右值小于11的节点即可。

    1. 获取某节点的子孙节点

    返回某节点子孙节点的前序遍历列表,以Fruit为例:

    SQL: SELECT* FROM Tree WHERE Lft BETWEEN 2 AND 11 ORDER BY Lft ASC

    查询结果如下:
    在这里插入图片描述
    那么某个节点到底有多少的子孙节点呢?

    通过该节点的左、右值我们可以将其子孙节点圈进来,则子孙总数 = (右值 – 左值– 1) / 2,以Fruit为例,其子孙总数为:(11 –2 – 1) / 2 = 4。

    同时,为了更为直观地展现树形结构,我们需要知道节点在树中所处的层次,通过左、右值的SQL查询即可实现。以Fruit为例:SELECT COUNT(*) FROM Tree WHERE Lft <= 2 AND Rgt >=11。为了方便描述,我们可以为Tree建立一个视图,添加一个层次数列,该列数值可以写一个自定义函数来计算,函数定义如下:

    CREATE FUNCTION dbo.CountLayer
    (
        @node_id int
    )
    RETURNS int
    AS
    begin
      declare @result int
      set @result = 0
      declare @lft int
      declare @rgt int
      if exists(select Node_id from Tree where Node_id = @node_id)
      begin
        select @lft = Lft, @rgt = Rgt from Tree where node_id = @node_id
        select @result = count(*) from Tree where Lft <= @lft and Rgt >= @rgt
      end
      return @result
    end
    GO
    

    基于层次计算函数,我们创建一个视图,添加了新的记录节点层次的数列:

    CREATE VIEW dbo.TreeView
    AS
    SELECT Node_id, Name, Lft, Rgt, dbo.CountLayer(Node_id) AS Layer FROM dbo.Tree ORDER BY Lft
    GO
    

    创建存储过程,用于计算给定节点的所有子孙节点及相应的层次:

    CREATE PROCEDURE [dbo].[GetChildrenNodeList]
    (
      @node_id int
    )
    AS
    declare @lft int
    declare @rgt int
    if exists(select Node_id from Tree where node_id = @node_id)
      begin
        select @lft = Lft, @rgt = Rgt from Tree where Node_id = @node_id
        select * from TreeView where Lft between @lft and @rgt order by Lft ASC
      end
    GO
    

    现在,我们使用上面的存储过程来计算节点Fruit所有子孙节点及对应层次,查询结果如下:
    在这里插入图片描述
    在进行树的查询遍历时,只需要进行2次数据库查询,消除了递归,再加上查询条件都是数字的比较,查询的效率是极高的,随着树规模的不断扩大,基于左右值编码的设计方案将比传统的递归方案查询效率提高更多。

    2. 获取某节点的族谱路径

    假定我们要获得某节点的族谱路径,则根据左、右值分析只需要一条SQL语句即可完成。

    以Fruit为例:SELECT* FROM Tree WHERE Lft < 2 AND Rgt > 11 ORDER BY Lft ASC

    相对完整的存储过程如下:

    CREATE PROCEDURE [dbo].[GetParentNodePath]
    (
      @node_id int
    )
    AS
    declare @lft int
    declare @rgt int
    if exists(select Node_id from Tree where Node_id = @node_id)
      begin
        select @lft = Lft, @rgt = Rgt from Tree where Node_id = @node_id
        select * from TreeView where Lft < @lft and Rgt > @rgt order by Lft ASC
      end
    GO
    

    3. 为某节点添加子孙节点

    假定我们要在节点“Red”下添加一个新的子节点“Apple”,该树将变成如下图所示,其中红色节点为新增节点。
    在这里插入图片描述
    相对完整的插入子节点的存储过程:

    CREATE PROCEDURE [dbo].[AddSubNode]
    (
      @node_id int,
      @node_name varchar(50)
    )
    AS
    declare @rgt int
    if exists(select Node_id from Tree where Node_id = @node_id)
      begin
        SET XACT_ABORT ON
        BEGIN TRANSCTION
        select @rgt = Rgt from Tree where Node_id = @node_id
        update Tree set Rgt = Rgt + 2 where Rgt >= @rgt
        update Tree set Lft = Lft + 2 where Lft >= @rgt
        insert into Tree(Name, Lft, Rgt) values(@node_name, @rgt, @rgt + 1)
        COMMIT TRANSACTION
        SET XACT_ABORT OFF
      end
    GO
    

    4. 删除某节点

    如果我们想要删除某个节点,会同时删除该节点的所有子孙节点,而这些被删除的节点的个数为:(被删除节点的右值 – 被删除节点的左值+ 1) / 2,而剩下的节点左、右值在大于被删除节点左、右值的情况下会进行调整。来看看树会发生什么变化,以Beef为例,删除效果如下图所示。
    在这里插入图片描述
    则我们可以构造出相应的存储过程:

    CREATE PROCEDURE [dbo].[DelNode]
    (
      @node_id int
    )
    AS
    declare @lft int
    declare @rgt int
    if exists(select Node_id from Tree where Node_id = @node_id)
      begin
        SET XACT_ABORT ON
        BEGIN TRANSCTION
          select @lft = Lft, @rgt = Rgt from Tree where Node_id = @node_id
          delete from Tree where Lft >= @lft and Rgt <= @rgt
          update Tree set Lft = Lft – (@rgt - @lft + 1) where Lft > @lft
          update Tree set Rgt = Rgt – (@rgt - @lft + 1) where Rgt > @rgt
          COMMIT TRANSACTION
        SET XACT_ABORT OFF
      end
    GO
    

    小结

    优点:

    • 消除了递归查询,实现了无限嵌套
    • 查询是基于整数的比较,效率很高

    缺点:

    • 节点的添加、删除及修改代价较大

    在基于数据库的一般应用中,查询的需求总要大于删除和修改,同时我们可以扩展MPT来实现更多的优化,例如:如果对层级需求较高,可以结合MPT和二中的方法来实现。

    Reference

    层次数据结构的数据表设计:https://juejin.cn/post/6844903861413478407#heading-7

    树形结构的数据库表Schema设计:https://blog.csdn.net/monkey_d_meng/article/details/6647488

    展开全文
  •  关系模型二维表结构来表示实体与实体之间联系,它是以关系数学理论为基础,每个二维表又可称为关系。  在关系模型中,操作对象和结果都是二维表,关系模型是目前最流行数据库模型。支持关系模型的...
  • 为解决人脑表面结构特征建模中CT以及MRI等二维图像显示所带来信息遗漏、观察不便等缺陷,提出了基于D-TIN(Delaunay TIN)剖分三维人脑表面模型建模策略。针对实体模型分层切片数据,以离散拟合思想为算法依据,...
  • 它是一种关系型数据库,存储了地理数据与非地理数据,和各种数据之间的关系,存储了CityMaker所定义的数据结构的数据。CityMaker将其操作过程封装在了数据引擎,用户不需要另外安装数据库即可读取。CityMaker...
  • 参照leetcode 695题 给定一个二维数组,a[i][j] == 1 (无向图)即为顶点,该顶点的坐标为 (i,j...2.可将该矩阵转换为邻接,邻接作为遍历时的数据结构我们比较熟悉。 下面介绍如何将这个矩阵转化为邻接。 在C...
  • 二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范。也称作行数据,数据以行为单位,一行数据表示一个实体的信息,每一行数据的属性是相同的。主要通过关系型数据库进行存储和管理。 半结构化数据...
  • 数据模型

    2020-09-15 17:37:14
    文章目录数据模型E-R模型(实体联系模型)数据模型关系模型关系中的数据约束 数据模型 数据模型的三要素:数据结构,数据操作和数据约束 数据模型按不同的应用层次分为: (1)概念数据模型:E-R模型 (2)逻辑数据...
  • 关系数据库里,关系模式(模型)是型,关系是值,关系模式...关系实质上是一个二维表,表中每一条记录(行)在关系模式中被称为元组,每个字段(列)被称为属性。 前者是描述结构,后者是具体数据。严格上不能划等号。
  • 是指由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理。也称作行数据,一般特点是:数据以行为单位,一行数据表示一个实体的信息,每一行数据的属性是相同的...
  • 数据模型(下)

    2020-04-22 14:20:37
    常见模型1.1层次模型1.1.1概述1.1.2层次模型的数据操作与完整性约束1.1.3层次模型的优缺点1.2网状模型1.2.1网状模型的数据操作与完整性约束...二维表的比较1.3.3关系模型的数据操作与完整性约束1.3.4 关系模型的优缺点...
  • 数据模型是指数据库的组织形式,它决定了数据库中数据之间联系的表达方式,即把在计算机中表示客观事物及其联系的数据结构称为数据模型。本文详细讲述传统三大数据模型和空间数据模型。 一、数据模型概述 数据模型...
  • 简单说就是数据库,也称作为行数据,是由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理。 2、半结构化数据 和普通纯文本相比,具有一定的结构性,但和具有...
  • 结构数据和非结构数据的区别

    千次阅读 2019-07-18 10:32:52
    结构化数据:结构化数据也称作行数据,是由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理。 (什么是关系型数据库:关系型数据库,是指采用了关系模型来...
  •   当所有维表都直接连接到**“ 事实表”**上时,整个图解就像星星一样,故将该模型称为星型模型,如图 1 。   星型架构是一种非正规化的结构,多维数据每一个维度都直接与事实表相连接,不存在渐变维度,...
  • 关系数据模型源于数学,它用二维表来组织数据,而这个二维表在关系数据库中称为关系。关系数据库就是表或者说是关系集合。 数据操作 关系数据模型给出了关系操作能力,包括。 传统运算关系:并(union)、交...
  • Pandas 是 python一个数据...Pandas 可以实现 SQL 中语句,对 DataFrame 操作相当于对二维表操作一样。还是以股票某天分笔记录为例。之前数据进行处理已经导入数据库。importnumpy as npimportpandas as p...
  • 结构化数据、半结构化数据和非结构化数据分析一、...结构化数据也称作行数据,是由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理。与结构化数据相对的是不适

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,139
精华内容 455
关键字:

二维表结构的数据模型