当前位置:  数据库>sqlserver
本页文章导读:
    ▪写给开发者看的关系型数据库设计      目录一 Codd的RDBMS12法则——RDBMS的起源二 关系型数据库设计阶段三 设计原则四 命名规则  数据库设计,一个软件项目成功的基石。很多从业人员都认为,数据库设计其实不那么重要.........
    ▪Sql语句积累      最近在给一家客户做系统维护时,需要查看数据库表的大小,相关的sql如下:1. exec sp_spaceused '表名'          --(SQL统计数据,大量事务操作后可能不准)2. exec.........
    ▪SQL挑战问题        群里面有位网友提出了这样一个SQL挑战问题(原话不是这样,为了说明问题,我略做调整些):问题说明如下有一条个销售报表TEST :商品 金额 A 1400 B 800 C 790... ...现在有这样一个需.........

[1]写给开发者看的关系型数据库设计
    来源:    发布时间: 2013-10-15

目录

一 Codd的RDBMS12法则——RDBMS的起源

二 关系型数据库设计阶段

三 设计原则

四 命名规则

  数据库设计,一个软件项目成功的基石。很多从业人员都认为,数据库设计其实不那么重要。现实中的情景也相当雷同,开发人员的数量是数据库设计人员的数倍。多数人使用数据库中的一部分,所以也会把数据库设计想的如此简单。其实不然,数据库设计也是门学问。

  从笔者的经历看来,笔者更赞成在项目早期由开发者进行数据库设计(后期调优需要DBA)。根据笔者的项目经验,一个精通OOP和ORM的开发者,设计的数据库往往更为合理,更能适应需求的变化,如果追其原因,笔者个人猜测是因为数据库的规范化,与OO的部分思想雷同(如内聚)。而DBA,设计的数据库的优势是能将DBMS的能力发挥到极致,能够使用SQL和DBMS实现很多程序实现的逻辑,与开发者相比,DBA优化过的数据库更为高效和稳定。如标题所示,本文旨在分享一名开发者的数据库设计经验,并不涉及复杂的SQL语句或DBMS使用,因此也不会局限到某种DBMS产品上。真切地希望这篇文章对开发者能有所帮助,也希望读者能帮助笔者查漏补缺。

一 Codd的RDBMS12法则——RDBMS的起源

  Edgar Frank Codd(埃德加·弗兰克·科德)被誉为“关系数据库之父”,并因为在数据库管理系统的理论和实践方面的杰出贡献于1981年获图灵奖。在1985年,Codd 博士发布了12条规则,这些规则简明的定义出一个关系型数据库的理念,它们被作为所有关系数据库系统的设计指导性方针。

  • 信息法则 关系数据库中的所有信息都用唯一的一种方式表示——表中的值。
  • 保证访问法则 依靠表名、主键值和列名的组合,保证能访问每个数据项。
  • 空值的系统化处理 支持空值(NULL),以系统化的方式处理空值,空值不依赖于数据类型。
  • 基于关系模型的动态联机目录 数据库的描述应该是自描述的,在逻辑级别上和普通数据采用同样的表示方式,即数据库必须含有描述该数据库结构的系统表或者数据库描述信息应该包含在用户可以访问的表中。
  • 统一的数据子语言法则 一个关系数据库系统可以支持几种语言和多种终端使用方式,但必须至少有一种语言,它的语句能够一某种定义良好的语法表示为字符串,并能全面地支持以下所有规则:数据定义、视图定义、数据操作、约束、授权以及事务。(这种语言就是SQL)
  • 视图更新法则 所有理论上可以更新的视图也可以由系统更新。
  • 高级的插入、更新和删除操作 把一个基础关系或派生关系作为单个操作对象处理的能力不仅适应于数据的检索,还适用于数据的插入、修改个删除,即在插入、修改和删除操作中数据行被视作集合。
  • 数据的物理独立性 不管数据库的数据在存储表示或访问方式上怎么变化,应用程序和终端活动都保持着逻辑上的不变性。
  • 数据的逻辑独立性 当对表做了理论上不会损害信息的改变时,应用程序和终端活动都会保持逻辑上的不变性。
  • 数据完整性的独立性 专用于某个关系型数据库的完整性约束必须可以用关系数据库子语言定义,而且可以存储在数据目录中,而非程序中。
  • 分布独立性 不管数据在物理是否分布式存储,或者任何时候改变分布策略,RDBMS的数据操纵子语言必须能使应用程序和终端活动保持逻辑上的不变性。
  • 非破坏性法则 如果一个关系数据库系统支持某种低级(一次处理单个记录)语言,那么这个低级语言不能违反或绕过更高级语言(一次处理多个记录)规定的完整性法则或约束,即用户不能以任何方式违反数据库的约束。
  • 二 关系型数据库设计阶段

    (一)规划阶段

      规划阶段的主要工作是对数据库的必要性和可行性进行分析。确定是否需要使用数据库,使用哪种类型的数据库,使用哪个数据库产品。

    (二)概念阶段

      概念阶段的主要工作是收集并分析需求。识别需求,主要是识别数据实体和业务规则。对于一个系统来说,数据库的主要包括业务数据和非业务数据,而业务数据的定义,则依赖于在此阶段对用户需求的分析。需要尽量识别业务实体和业务规则,对系统的整体有初步的认识,并理解数据的流动过程。理论上,该阶段将参考或产出多种文档,比如“用例图”,“数据流图”以及其他一些项目文档。如果能够在该阶段产出这些成果,无疑将会对后期进行莫大的帮助。当然,很多文档已超出数据库设计者的考虑范围。而且,如果你并不精通该领域以及用户的业务,那么请放弃自己独立完成用户需求分析的想法。用户并不是技术专家,而当你自身不能扮演“业务顾问”的角色时,请你选择与项目组的相关人员合作,或者将其视为风险呈报给PM。再次强调,大多数情况,用户只是行业从业者,而非职业技术人员,我们仅仅从用户那里收集需求,而非依赖于用户的知识。

      记录用户需求时,可以使用一些技巧,当然这部分内容有些可能会超出数据库设计人员的职责:

    • 努力维护一系列包含了系统设计和规格说明信息的文档,如会议记录、访谈记录、关键用户期望、功能规格、技术规格、测试规格等。
    • 频繁与干系人沟通并收集反馈。
    • 标记出你自己添加的,不属于客户要求的,未决内容。
    • 与所有关键干系人尽快确认项目范围,并力求冻结需求。

      此外,必须严谨处理业务规则,并详细记录。在之后的阶段,将会根据这些业务规则进行设计。

      当该阶段结束时,你应该能够回答以下问题:

    • 需要哪些数据?
    • 数据该被怎样使用?
    • 哪些规则控制着数据的使用?
    • 谁会使用何种数据?
    • 客户想在核心功能界面或者报表上看到哪些内容?
    • 数据现在在哪里?
    • 数据是否与其他系统有交互、集成或同步?
    • 主题数据有哪些?
    • 核心数据价值几何,对可靠性的要求程度?

      并且得到如下信息:

    • 实体和关系
    • 属性和域
    • 可以在数据库中强制执行的业务规则
    • 需要使用数据库的业务过程

    (三)逻辑阶段

      逻辑阶段的主要工作是绘制E-R图,或者说是建模。建模工具很多,有不同的图形表示方法和软件。这些工具和软件的使用并非关键,笔者也不建议读者花大量时间在建模方法的选择上。对于大多数应用来说,E-R图足以描述实体间的关系。建模关键是思想而不是工具,软件只是起到辅助作用,识别实体关系才是本阶段的重点。

      除了实体关系,我们还应该考虑属性的域(值类型、范围、约束)


        
    [2]Sql语句积累
        来源:    发布时间: 2013-10-15

    最近在给一家客户做系统维护时,需要查看数据库表的大小,相关的sql如下:

    1. exec sp_spaceused '表名'          --(SQL统计数据,大量事务操作后可能不准)
    2. exec sp_spaceused '表名', true       --(准确的表空间大小,但可能会花些统计时间)
    3. exec sp_spaceused                   -- (数据库大小查询)
    4. exec sp_MSforeachtable "exec sp_spaceused '?'"     --(所有用户表空间表小,SQL统计数据,,大量事务操作后可能不准)
    5. exec sp_MSforeachtable "exec sp_spaceused '?',true"    --(所有用户表空间表小,大数据库慎用)

    本文链接


        
    [3]SQL挑战问题
        来源:    发布时间: 2013-10-15

     

     

    群里面有位网友提出了这样一个SQL挑战问题(原话不是这样,为了说明问题,我略做调整些):

    问题说明如下

    有一条个销售报表TEST :

    商品 金额

    A 1400

    B 800

    C 790

    ... ...

    现在有这样一个需求(要写一个SQL取出如下数据):先按销售金额倒叙排序,然后从这个报表取出前N条记录,并且这N条记录的销售金额之和是总金额的80%(<= 80%), 80%将作为一个查询条件(有可能是20%,30%).他的想法是用嵌套函数 递归做法记录砍掉一半判断是否达到百分比 如果不足再取后半部分的一半 类似这样的方法;还有就是逐行金额相加当金额到达80%的时候 记录就从头显示到该条的前一条。 现在他想有没有其他跟高效的方法来实现这个需求?

    那么我看到这个问题的时候,觉得有嵌套函数递归处理的方法的效率肯定是最低的,毕竟SQL不擅长于做逻辑处理。那么有没有更好的方法来实现呢?大家在看后面方法的时候,可以思考一下有没有更好的方法,能够达到一击必杀的效果(一个SQL搞定)。欢迎大家探讨!

    下面是我的一个解决思路和方法,我在按销售金额倒叙排列的时候,能否得到一个销售金额的累加值?然后把这个累加值除以销售总金额即得到累加金额占总金额的一个比例,然后我们再加上查询条件。即可解决问题。

    新建一个测试表TEST

     

    CREATE TABLE TEST

    (

      PRODUCT_NAME CHAR(32), --商品名称

      SALE_AMOUNT FLOAT    --销售金额

    )

     

    插入测试数据

    INSERT INTO TEST

    SELECT 'A' ,13000 UNION ALL

    SELECT 'A' ,12000 UNION ALL

    SELECT 'A' ,9000 UNION ALL

    SELECT 'B' ,167000 UNION ALL

    SELECT 'B' ,137000 UNION ALL

    SELECT 'B' ,107000 UNION ALL

    SELECT 'C' ,78000 UNION ALL

    SELECT 'C' ,12000;

     

    实现销售金额的累加值字段的脚本(这个脚本效率没有测试,小量数据应该没有问题)

    SELECT ROW_NUMBER() OVER (ORDER BY SALE_AMOUNT DESC ) AS ROW,PRODUCT_NAME,

    T.SALE_AMOUNT,

    (SELECT SUM(SALE_AMOUNT) AS ACCUMATE_SALE FROM TEST WHERE T.SALE_AMOUNT <= SALE_AMOUNT ) AS ACCUMATE_SALE

    FROM TEST T

     

            (截图)

    那么接下来我们来实现上面的思路

    SELECT ROW_NUMBER() OVER(ORDER BY T.SALE_AMOUNT DESC) AS ROW,

    T.PRODUCT_NAME,

    T.SALE_AMOUNT,

    (SELECT SUM(SALE_AMOUNT) SUM_SALE

    FROM TEST

    WHERE T.SALE_AMOUNT <= SALE_AMOUNT) / L.SALE_AMOUNT AS SUM_RAT

    FROM TEST T, (SELECT SUM(SALE_AMOUNT) AS SALE_AMOUNT FROM TEST) L

     

          截图

    接下来就水到渠成了

    SELECT T.ROW, T.PRODUCT_NAME, T.SALE_AMOUNT, T.SUM_RAT FROM

    (

    SELECT ROW_NUMBER() OVER(ORDER BY T.SALE_AMOUNT DESC) AS ROW,

    T.PRODUCT_NAME,

    T.SALE_AMOUNT,

    (SELECT SUM
        
    最新技术文章:
    ▪Sql Server里删除数据表中重复记录的例子
    ▪如何查看SQLSERVER中某个查询用了多少TempDB空间...
    ▪在SQL Server中使用ISNULL执行空值判断查询
    ▪揭秘SQL Server 2014有哪些新特性(1)-内存数据库
    ▪揭秘SQL Server 2014有哪些新特性(2)-固态硬盘 Buff...
    ▪揭秘SQL Server 2014有哪些新特性(3)-可更新列存...
    ▪揭秘SQL Server 2014有哪些新特性(4)-原生备份加...
    ▪解决SqlServer 各版本 sa帐户不能登录问题
    ▪浅析SQL Server中包含事务的存储过程
    ▪深入分析MSSQL数据库中事务隔离级别和锁机制
    ▪SQL优化技巧指南
    ▪人工智能自动sql优化工具--SQLTuning for SQL Server
    ▪使用 TOP 子句限制UPDATE 语句更新的数据
    ▪sql server动态存储过程按日期保存数据示例
    ▪SQLServer用存储过程实现插入更新数据示例
    ▪SqlServer中tempdb的日志机制原理解析及示例分享...
    ▪SqlServer数据库提示 “tempdb” 的日志已满 问题...
    ▪浅谈tempdb在SqlServer系统中的重要作用
    ▪SqlServer提示“列前缀tempdb.无效: 未指定表名”...
    ▪SQL命令优化需要记住的9点事项
    浙ICP备11055608号-3 iis7站长之家
    ▪sql server 2000数据库备份还原的图文教程
    ▪SqlServer2012中First_Value函数简单分析
    ▪sql语句中单引号嵌套问题(一定要避免直接嵌...
    ▪谈谈sqlserver自定义函数与存储过程的区别
    ▪SQL SERVER使用REPLACE将某一列字段中的某个值替...
    ▪总结一周内学习的Sql经验(一)
    ▪sql存储过程详解
    ▪SQL Server UPDATE语句的用法详解
    ▪MSSQL事务的存储过程
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3