数据库设计技巧

2023-11-03

如今, 随着软件应用领域的扩大,我们要处理的数据也越来越多, 面对各式各样的数据, 我怎么样系统的保存和管理这些数据呢 。
这里我们就要采用关系型数据库。 关系型数据库是当前最广泛的应用的数据库类型,如mysql oracle access 等等 很多。 关系数据库的设计就是对数据进行组织化和结构化的过程。 要想设计好一个关系型的数据库,我们就必须得遵从科学的设计规则! 当我们设计的数据库规模较小时候, 可以比较轻松的处理数据库中的表结构, 然而 我们的项目很大时,涉及的数据与数据之间的关系越来越复杂的时候,关系数据库的设计就很庞大了, 如果表格的定义不合理, 就会导致 数据的更新和删除不完整。这时候我们要写的sql语句也是很笨拙的,并且查找的效率很是底下, 为了科学的设计数据库,减少数据的冗余和错乱,提高数据的可扩展性,我们要遵从数据库设计的规范化流程。
一、 数据库设计的规范有三范式:
1. 第一范式(1NF)无重复的列

所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。简而言之,第一范式就是无重复的列。

说明:在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。


2. 第二范式(2NF)属性完全依赖于主键[消除部分子函数依赖]

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。例如员工信息表中加上了员工编号(emp_id)列,因为每个员工的员工编号是惟一的,因此每个员工可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是属性完全依赖于主键。


3. 第三范式(3NF)属性不依赖于其它非主属性[消除传递依赖]

满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在的员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。

二、当我遇到的实体是多对多的关系的时候我们要善于正确处理多对多的关系
若两个实体之间存在多对多的关系,则应消除这种关系。消除的办法是,在两者之间增加第三个实体。这样,原来一个多对多的关系,现在变为两个一对多的关系。要将原来两个实体的属性合理地分配到三个实体中去。这里的第三个实体,实质上是一个较复杂的关系,它对应一张基本表。一般来讲,数据库设计工具不能识别多对多的关系,但能处理多对多的关系。

〖例3〗:在“图书馆信息系统”中,“图书”是一个实体,“读者”也是一个实体。这两个实体之间的关系,是一个典型的多对多关系:一本图书在不同时间可以被多个读者借阅,一个读者又可以借多本图书。为此,要在二者之间增加第三个实体,该实体取名为“借还书”,它的属性为:借还时间、借还标志(0表示借书,1表示还书),另外,它还应该有两个外键(“图书”的主键,“读者”的主键),使它能与“图书”和“读者”连接。


三、当然对于以上的三范式,对于不同的需求也有不同的侧重点:
比如我们要正确的认识和处理数据冗余的问题, 这里声明一点 主键与外键在多表中的重复出现,不属于数据的冗余,我们必须认识到这点,只要非关键字的重复出现才是 数据的冗余!而且是一种低级冗余,即重复性的冗余。高级冗余不是字段的重复出现,而是字段的派生出现。
〖例4〗:商品中的“单价、数量、金额”三个字段,“金额”就是由“单价”乘以“数量”派生出来的,它就是冗余,而且是一种高级冗余。冗余的目的是为了提高处理速度。只有低级冗余才会增加数据的不一致性,因为同一数据,可能从不同时间、地点、角色上多次录入。因此,我们提倡高级冗余(派生性冗余),反对低级冗余(重复性冗余)。

总之,要提高数据库的运行效率,必须从数据库系统级优化、数据库设计级优化、程序实现级优化,这三个层次上同时下功夫。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据库设计技巧 的相关文章

  • Oracle 语法 - 我们是否必须在新旧语法之间进行选择?

    我在一个由大约 8 名开发人员组成的团队中负责大约 1 000 000 行源代码的代码库 我们的代码基本上是一个使用 Oracle 数据库的应用程序 但代码随着时间的推移而不断发展 我们有大量九十年代中期的源代码 团队中就我们用于查询 Or
  • MySQL“LIKE”搜索不起作用

    我通过 LOAD DATA INFILE 在 MySQL 中导入了一个 txt 数据库 一切似乎都正常 唯一的问题是 如果我使用以下查询在数据库上搜索记录 SELECT FROM hobby WHERE name LIKE Beading
  • Google Cloud SQL 在重新启动时卡住

    我的云 sql 实例长时间处于重新启动状态 在操作窗格中 重新启动的状态显示为待处理 并且还发生了导出 其状态仍为Running 有没有办法可以强制重新启动或取消重新启动或从常规备份中恢复数据 不 没有办法 如果您向 Google 支付高级
  • mysql转储到derby

    我正在使用 derby 在 eclipse 中进行开发 是否可以从 MySQL 转储表并以某种方式将其用于 derby 我知道 ddl 和 dml 对于两个 dbms 来说是不同的 但我正在寻找一种除了转储 导出之外的合适方法 我可以找到两
  • 每月获取记录,但如果该月没有记录,则为零

    如果我有以下 SQL 表 Tests id type receiveDate 1 Blood 2012 01 18 2 Blood 2012 01 20 3 Blood 2012 01 18 4 Blood 2012 03 01 5 Blo
  • 如果 Row1 = 值 1,则更新其他行

    我有一个小的 php 脚本 用于访问 mySql 数据库 我想在数据库中插入新记录之前查看该数字 值 1 是否等于数据库中的记录 这也在第 1 行 所以我想 查看传入的电话号码是否等于数据库中的电话号码 如果是这样 则必须保持电话号码相同的
  • MySQL 排序顺序 - 排序规则?

    我在对 MySQL 中的 char 字段进行排序时遇到困难 问题是重音字符与非重音字符混淆 例如 Abc bd Acc 我认为这可能与整理有关 所以我将表格的排序规则更改为utf8 ut8 bin 看完之后这个帖子 https stacko
  • 慢速自动增量重置

    我有很多表 由于某些原因 我需要在应用程序启动时调整这些表的自动增量值 我尝试这样做 mysql gt select max id from item max id 97972232 1 row in set 0 05 sec mysql
  • 如何从批量数据中的mysql列中删除所有非数字字符

    我想从列中删除所有非数字字符 我的数据库中有大量数据 目前我正在使用以下链接中描述的方法 http venerableagents wordpress com 2011 01 29 mysql numeric functions http
  • 让登录更安全

    我已使用此代码进行管理员登录 仅当用户输入正确的用户名和密码时才应打开loginhome php 但后来我意识到这根本不安全 任何人都可以直接访问 mywebsite loginhome php 而无需登录 注销后 可以使用后退按钮打开 l
  • ORDER BY 字段内的 MySQL 子查询。 (没有内连接)

    有很多与此相关的问题 但都具有使用内部联接的相同答案 这 我认为 在这里是不可能的 如果我错了请告诉我 我现在正在做的是调用两个不同的 mysql 查询来获取结果 它工作完美 db gt query SELECT FROM meta WHE
  • 如何在java 1.8中从org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8转换为oracle.jdbc.OracleConnection

    如何在 java 1 8 中从 org jboss jca adapters jdbc jdk8 WrappedConnectionJDK8 转换为 oracle jdbc OracleConnection 目前我正在这样使用并得到以下异常
  • MySQL/PDO::quote() 尽管使用 PDO::PARAM_INT 参数,但仍在整数周围加上引号

    无论我传递给什么值 数据类型对 它都会出现 pdo gt quote value type 它总是将其引用为字符串 echo pdo gt quote foo PDO PARAM STR foo as expected echo pdo g
  • PHP MySQL 使用选项/选择 HTML 表单标签进行多重搜索查询

    我正在尝试使用两个搜索字段设置基本的 MySQL LIKE 搜索 我不想拥有它 所以它有多个可选搜索字段 例如if isset POST city isset POST name 我不知道如何用 HTML 来做到这一点
  • 删除行导致锁超时

    当我尝试从表中删除行时 我不断收到这些错误 这里的特殊情况是我可能同时运行5个进程 该表本身是一个 Innodb 表 约有 450 万行 我的 WHERE 子句中使用的列没有索引 其他指数按预期运行 这是在事务中完成的 首先删除记录 然后插
  • 获取带有计数的不同记录

    我有一张桌子personid and msg列 personid msg 1 msg1 2 msg2 2 msg3 3 msg4 1 msg2 我想得到总计msg对于每个personid 我正在尝试这个查询 select distinct
  • posts_search 中的自定义查询

    如何使用此查询作为我的自定义搜索查询 add filter posts search my search is perfect 20 2 function my search is perfect search wp query sWord
  • MySQL 与日语字符

    我试图弄清楚如何创建一个表 以便我可以在其中插入日语名字 现在我有 Type InnoDB Encoding UTF 8 Unicode utf8 Collation utf8 general ci 但是 当我插入字符时 它显示为 当我使用
  • PHP 与 MySQL 查询性能( if 、 函数 )

    我只看到这个artice http www onextrapixel com 2010 06 23 mysql has functions part 5 php vs mysql performance 我需要知道在这种情况下什么是最好的表
  • 通知设置的数据库设计

    用户可以打开或关闭 他的通知设置 帐户 用于通知 例如 更改帐户资料信息 收到新消息等 通知可以通过电子邮件或手机 推送或短信 发送 用户可以只有 1 封电子邮件和多个手机设备 有什么方法可以改进以下数据库设计或者您会采取不同的方式吗 让我

随机推荐

  • 30道软件测试高频面试题

    如果哪个测试经理在看我的文章 希望对面试者要微笑 不然面试结束 出门之后就一万个草泥马奔腾而过 其实面试者并不是希望你给他们什么 而是一种尊重 平等的谈话 不要高高在上感觉自己超牛逼一样 任何大牛都是从菜鸟起步的 当然 正在学习测试技术的人
  • VUE之Vxe-table动态生成多级表头

    需求 1 第一列为正常列 2 第二列开始为动态生成列 根据接口返回数据生成 3 最后一列为编辑列 实现步骤 模板中定义
  • Java 类的主动使用和被动使用

    Java程序对类的使用方式分为 主动使用和被动使用 主动使用 又分为七种情况 1 创建类的实例 2 访问某个类或者接口的静态变量 或者对该静态变量赋值 3 反射 比如 Class forName java lang String 4 初始化
  • 代码漏洞说明

    1 代码注入 命令注入 命令注入是指 在应用程序执行的命令中包含来源于不可信数据时 程序本身没有对这些不可信数据做正确 合理的验证和过滤 导致系统执行恶意命令 例1 以下代码通过Runtime exec 方法调用Windows的dir命令
  • PID简介

    一 基本定义 Sv 用户设定值 给定信号 Pv 控制对象当前状态值 反馈信号 E 偏差值 偏差信号 所以 E Sv Pv 二 PID各个控制基本分析 1 P控制 比例控制 Pout Kp Ek 假定从早上开机上电 我们每隔一秒钟就通过传感器
  • html5的session,HTML5 sessionStorage会话存储

    sessionStorage 是HTML5新增的一个会话存储对象 用于临时保存同一窗口 或标签页 的数据 在关闭窗口或标签页之后将会删除这些数据 本篇主要介绍 sessionStorage 会话存储 的使用方式 包括添加 修改 删除等操作
  • c++语言的学习——判断闰年

    判断闰年 描述 判断某年是否是闰年 输入 输入只有一行 包含一个整数a 0 lt a lt 3000 输出 一行 如果公元a年是闰年输出Y 否则输出N 样例输入 2006 样例输出 N 提示 公历纪年法中 能被4整除的大多是闰年 但能被10
  • Wireshark的两种过滤器与BPF过滤规则

    Wirshark使用的关键就在于过滤出想要的数据包 下面介绍怎么过滤 抓包过滤器 Wirshark有两种过滤器 一个是抓包过滤器 一个是显示过滤器 他们之间的区别在于抓包过滤器只抓取你设置的规则 同时丢弃其他信息 显示过滤器并不会丢弃信息
  • Qt之UDP通信

    目录 一 UDP简介 二 QUdpSocket类 三 UDP服务器 四 UDP客户端 五 代码 1 udp服务端 2 udp客户端 一 UDP简介 UDP User Datagram Protocol 即用户数据报协议 是一个轻量级的 不可
  • 如何使用Jekyll在GitHub Pages上搭建网站(个人博客)

    前言 本文很长 建议使用侧边栏进行跳转 Jekyll 是一个基于 Ruby 语言的 用于搭建静态网站的生成器 主要用于搭建博客网站 官方自己的介绍为 Jekyll is a blog aware static site generator
  • “error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed”解决方法

    使用git通过https方式从github clone git repo源码时 报错如下 1 2 3 Cloning into git fatal unable to access https github com git git git
  • 【用JS自制表格软件玩数据】8. 设计单元格中的右键菜单

    右键菜单选项的设计 效果图 基本数据 分析 功能 菜单的渲染模块 右键菜单的样式 最终结果 当写完本系列后 我会把源代码分享出来给大家 本课程也会持续更新与矫正 欢迎留言指正 效果图 基本数据 首先构建一个基本的配置数据 property
  • 【历史上的今天】1 月 9 日:iPhone 问世;iTunes 发布;激光打印机的发明者出生

    整理 王启隆 透过 历史上的今天 从过去看未来 从现在亦可以改变未来 今天是 2023 年 1 月 9 日 在 1978 年的这段时间 我国恢复了研究生制度 这一年 共录取了 10500 多名研究生 研究生教育的中断和复兴是一个漫长的过程
  • Linux中利用docker搭建深度学习环境

    写在前面 在深度学习中 避免不了在远程服务器上进行模型的训练 如果直接在服务器裸机的基础环境跑显然是不可取的 此时搭建用于模型训练的docker环境显得尤为重要 1 下载基础镜像 选择一个合适的基础镜像会给后续的操作带来极大的便利 其中uf
  • centos7安装redis

    文章目录 一 准备工作 二 安装redis 三 配置redis 四 配置redis服务 五 其他 一 准备工作 关闭防火墙等 linux时间校对 试验环境 虚拟机服务器版本 centos7 虚拟机IP地址 192 168 1 10 win端
  • uniapp在H5获取当前定位信息不需要SDK可直接获取城市(包括经纬度省市区和市区编码)

    前言 最近在做获取用户当前定位信息的时候 发现uniapp官方提供的uni getLocation OBJECT 兼容性并不是特别好 光注意事项都是密密麻麻一大堆 在实际使用场景下 效果并不理想 也不是很稳定 于是便重新封装了一下腾讯地图的
  • JUC-多线程(5.获得线程的第三种方式)学习笔记

    文章目录 获得线程的第三种方式 Callable接口 1 前言 1 获得多线程的方法几种 2 以下两种获得线程的方式的异同 2 使用 1 重写 call 方法 2 创建线程 3 获取返回值 3 原理 1 简述 2 解释 3 结论 获得线程的
  • 关于加速度计读数与加速度方向的问题

    近几日对加速计读数的正负与其敏感轴 实际加速度计方向的关系又产生了诸多疑问 参考这篇博文的一个模型后 更是混乱了 http www geek workshop com forum php mod viewthread tid 1695 re
  • Kotlin Primer·第三章·Kotlin 与 Java 混编

    虽然 Kotlin 的开发很方便 但当你与他人协作时 总会碰到 Java 与 Kotlin 代码共存的代码项目 本章就教你如何优雅的实现 Kotlin 与 Java 混合编程 3 1 直接转换 3 1 1 将 Java 转换为 Kotlin
  • 数据库设计技巧

    如今 随着软件应用领域的扩大 我们要处理的数据也越来越多 面对各式各样的数据 我怎么样系统的保存和管理这些数据呢 这里我们就要采用关系型数据库 关系型数据库是当前最广泛的应用的数据库类型 如mysql oracle access 等等 很多