【数据库应用】一种神奇的建表(图?)方式:点与连线建表(图?)法

原先的问题:

  第一次社团任务是写个图书管理系统,理所当然用到了数据库。

  废话不多说直接上表:

  第一次做这种东西,都是边摸索边设计,于是理所当然被大牛指出了不足之处,比如adminlist其实有点多余。

  提几个让人抓狂的问题:

  1、当你设计好了books表,一本书可以有书名、种类、作者等属性,并且你已经添加了上百本书进去的时候,客户突然要求你加个“适合阅读人群”的属性。

  2、一本书一个kind,貌似没什么问题。但是,用户可以借阅多本书,书也可以被多个用户借阅,一开始考虑时“书”与“用户”多对多的关系很容易被想到。但谁也不能保证自己没漏掉任何情况。于是到后期,突然发现书和kind也有个多对多的要求,拓展下,客户希望你把书和作者也改成多对多的关系……

  (╯‵□′)╯︵┻━┻

新型建表法:

  把所有的数据按照“值”,“属性”方式保存成一个个点。再表达点与点间的连线关系。

  初步想法是建3张表:

    表1:数据点

      列名    :id(主键),数据                                                      ,类型id

      值类型:int              ,maxchar (这里是因为当时还没想好),int

    表2:类型

      列名    :id(主键),类型

      值类型:int              ,maxchar

    表3:连线

      列名    :id(主键),点1的id    ,点2的id

      值类型:int              ,int            ,int

  这种东西建好以后是什么概念呢?

  比如要做用户管理,最简单的,用户只有用户名及密码。

    那首先在表2里添加 “用户名”,“密码”两个类型。

    然后添加用户时,相当于建立两个节点,一个节点的类型是“用户名”,一个节点的类型是“密码”,然后数据那一栏里就是...就是你们想的那样。

    最后再在表3连线那里给这两个点条线,大功告成。

  好了,如果客户突然抽风,要求你给用户再加个属性表示这人喜欢吃什么。

    在类型表里添加“喜欢吃啥”。

    建点,连线,ok。

  查询时,先查出某个用户的所有连线,再根据连到的点的类型筛选你需要的点。比如一个查一个用户的所有借阅书籍可以这么查:先查与 数据为XX 类型为“用户名” 的节点连线的所有节点,然后筛选其中所有类型为“图书”的点,然后取出数据,就完成了。说起来复杂,其实写到sql语句里就一行。

改进:

  好了,有个很明显的缺陷,不知道你们有没有看出来。

  数表1的数据那一栏,值是maxchar,各种编程语言里可以用object啥的表示,用的时候再强制转类型,但是数据库只能苦逼地用...用什么表示都不对。于是可以这么改:

    表2表3不变

    表1:

      列名:id  ,数据所在类型的表名         ,表内id,类型id

      值    :int,表名一般是char[20]以内吧,int       ,int

    表4~n:

      列名:id   ,数据                   ,对应表1的id

      值    :int ,杂七杂八的类型 ,int

  改了下数据的索引方式,这样就方便起来了。

这种表(图?)的优缺点:

  优点:

    对存储数据储存方式的变更极其灵活,多对多 多对一 一对多不在话下,而且随时可以添加新的类型。

  缺点:

    面对大量数据(百万级千万级)就呵呵了,因为要查询用户O(n)*查询连线O(m)*查到另一个点O(n)*筛选O(1?)。(不过考虑到数据库的索引方式,如果写的好的话没准是O(logn)?)

 

转载于:https://www.cnblogs.com/Bushiczl/p/7795032.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值