• 关于数据库设计的重要性


    关于数据库设计的重要性

      web开发是面向数据集的开发,我们开发人员对现实世界的抽象的一步就是建立表(或者你可以理解成类),而且在关系型数据的设计中,我是非常看重三范式!!!非常!!!,因为table是一切的源头,如果你的表设计不合理;那么你上层的代码也跟着错;而且后面的设计,将会错的各种离谱,我已经不想吐槽!!

    这里,我会屡屡序序的完整这篇文章,讲讲个人对三范式的理解和它重要性;我们先提概念,再结合实际来一步一步的分析;

    我先从简单的,一步一步的深入; 

    总的来说分成两部分!

    1.实体的设计

    2.实体关系的设计

    实体设计原则一:原子性,不可分割性

            比如product 中有一字段是价格,而我们的价格可以继续再分(进价 卖价);如果设计为一个字段,将带来一定的模糊性

    实体设计原则二:完全依赖主键,不存在部分依赖(可以理解成一个表只存一个实体相关的信息)

          sId,name,classNo,className

     这样的设计,明显不合理,应该拆分成两个表

    实体设计原则三:不存在非主键属性之间的依赖(就是字段与字段之间不存在依赖性)

         这一点是对第二原则的进一步补充;如:jobName 和 jobDescript 两个字段就有一定的依赖性;如果存在这样的依赖,就会导致jobDescript的重复出现;

    其实,跟人觉得这个问题都不大~

    2.实体关系的设计

    1.一对一

    2.一对多

    3. 多对多

     关系的设计体现在我们的设计的合理性和约束的合理性;

    问题一,关系混乱,将jion后的数据数据,记录在一张表中!

    如: 

    张三 语文 60

    张三 数学 70

    张三 外语 80

    这个数据应该是,姓名表,课程表,成绩表,三张表jion之后的数据!!而不是所谓的“”成绩表“”,如果就这样设计,我们看看带来的问题;

    1.Create

    一数据重复:

      1.姓名重复:明显看出如果,张三选了十门课程,那么张三会重复十次!

      2.课程重复:明显看出如果,语文背全班60个同学选择,那么结果就是语文会重复60次!

    2.修改
      

    还有一种关系如:产品类别和产品之间的关系建立(应该是一对多,应该没问题吧);

    假设,我们这里用codefirst 方式来模拟建表的过程;

    比如,一个类别有多个产品;表设计如下!!!

        /// <summary>
        /// 类别信息;
        /// </summary>
        public class Category
        {
            public string Id { get; set; }
    
            public string CategoryName { get; set; }
    
            public string Remark { get; set; }
    
            public string ProuductIds { get; set; }
    
        }

    产品表

        /// <summary>
        /// 产品表
        /// </summary>
        public class Product
        {
            public string Id { get; set; }
    
            public string Name { get; set; }
    
        }

    类别和产品的关系我们通过ProuductIds 关联起来,中间用逗号分开!!也就想像这样(1,2,3,4,5)

    然后,我们来看存在的问题;

    1.Create

           Insert into Category(CategoryName,Remark,ProductIds) values ('nicke鞋','鞋','1,2,3,4,5,6')  --假设有五种产品;

    问题,如果6 这个产品不存在,导致的结果就是:添加不存在的产品!!!

    2.Update

     更新到简单,我们可以直接覆盖原来的数据;把ProductIds=(‘1,2,3,4,5,6’)  跟新为 ProductIds=(‘1,2,3,7’) 

    问题:由于缺乏数据一致性的约束,我们同样可能将不存在的数据(产品)添加进去

    3.Delete

         如果是全部删除,那还没什么问题,直接清空,ProductIds=(‘1,2,3,4,5,6’)  跟新为 ProductIds=(‘’) 

     如果只是更新部(删除)部分呢,同样,由于缺乏数据一致性的约束,导致,我们更新一些,不存在的产品;

    正确的设计应该是,在Product中建立外键关联;如下

        /// <summary>
        /// 产品类别信息;
        /// </summary>
        public class Category
        {
            public string Id { get; set; }
    
            public string CategoryName { get; set; }
    
            public string Remark { get; set; }
    
        }
    
        /// <summary>
        /// 产品表
        /// </summary>
        public class Product
        {
            public string Id { get; set; }
    
            public string Name { get; set; }
    
            public string CategoryId { get; set; }
        }

    上面的设计,其实体现的是主外键的约束的重要性;如果少了约束可能导致的问题

    1.Create

    添加一个不存在的数据!(如在添加产品是,你将该产品附属到一个不存在的类别上!)

    2.Detele

    删除一个有依赖项目数据!如(某个角色下还有用户,你就将用户个删除了!)

    3.Update

      更新得不到通知!

    数据冗余问题一!

    在实际的开发中,我们可能常常会获取产品名称的同时获取他的额产品类别名称;有些同学为了获取方便(避免join获取数据)设计成这样!

        /// <summary>
        /// 产品表
        /// </summary>
        public class Product
        {
            public string Id { get; set; }
    
            public string Name { get; set; }
    
            public string CategoryId { get; set; }
    
            /// <summary>
            /// 产品名称
            /// </summary>
            public string CategoryName { get; set; }
        }

    在添加的是偶,添加产品信息的同时 保存 CategoryId的同时,保存CategoryName;!!!

    这样在查询的时候,确实方便了不少,因为不用join去获取类别名称,但是问题来了;!!

    如果Category 表中CategoryName改变了,你是不是要改变Product表中的CategoryName呢?

    所以建议不要去冗余那个CategoryName!因为category中的数据更新,product 中的数据得不到”更新通知”

    这样就无法维持数据的一直性!!!!!

    数据冗余问题二!

    还有一些关于数据不合理,然后导致数据冗余,居然有些开发者,说为了提高查询效率,避免jion;真的醉了;

    我们来看实际的场景;在关系型数据库中,主外键的约束带来了数据一致性的维护!同时也带了一个查询的问题;

    那就是我们的join的代价,(这个也是我们nosql出现的重要原因);这里要强调的是“千万别装逼!”,不要很小的数据,也在哪里提什么join的代价!shit!

    noslq的应用场景;

    1.对数据的一致性要求不高;

    2.外键相关联的表的数据表的变动非常小,

    3.数据量特别,根本不敢去join!

    如:

        博客,和评论;和评论的信息,如果每次去取数据都通过join的话,那么开销是非常大的;而且评论一旦定了之后,变的几率比较小;

       我们就可以利用MongoDB,json方式,存储这种结构化的数据!

    {
      "type": "post",
      "name": "Raven's Map/Reduce functionality",
      "blog_id": 1342,
      "post_id": 29293921,
      "tags": ["raven", "nosql"],
      "post_content": "<p>...</p>",
      "comments": [
        { 
          "source_ip": '124.2.21.2',
          "author": "martin",
          "text": "..."
      }]
    }

    数据库的设计了体现了我们队现实世界的抽象过程!那么往一一层走就是我们oop设计的能力了,也就是我们c#的写的能力了!

  • 相关阅读:
    可变长参数
    函数的参数
    函数
    文件操作
    字符编码
    数据类型的内置方法:集合
    数据类型的内置方法:元组
    数据类型的内置方法:字典
    数据类型内置方法:列表
    js对对象引用
  • 原文地址:https://www.cnblogs.com/mc67/p/8329224.html
Copyright © 2020-2023  润新知