찾다
데이터 베이스MySQL 튜토리얼我所遵守的11条数据库设计准则

我所遵守的11条数据库设计准则

Jun 07, 2016 pm 04:00 PM
작가기준머리말데이터 베이스설계

前言:作者Shivprasad koirala,前微软ASP/ASP.NET的MVC工程师,现于印度任CEO职位。学生初次翻译,如有不妥,不吝赐教。 简介 在你开始阅读这篇文章之前,我要先告诉你我不算是数据库设计方面的什么大师。下面的11条准则,是我从项目、从我自身的经验和我自

前言:作者Shivprasad koirala,前微软ASP/ASP.NET的MVC工程师,现于印度任CEO职位。学生初次翻译,如有不妥,不吝赐教。

简介

在你开始阅读这篇文章之前,我要先告诉你我不算是数据库设计方面的什么大师。下面的11条准则,是我从项目、从我自身的经验和我自己的理解和学习中得来的。我个人认为在数据库设计方面运用这些准则能使我受益匪浅。我也欢迎任何批评与指点。

我之所以要写这么一篇详尽的文章,是因为,许多开发者设计数据库的时候十分信奉“三个范式”(译者注:而没有结合实际情况)。他们认为三范式是数据库设计的唯一真谛。随着项目开发的不断推进,持有这些想法的人会经常碰壁和遇上无穷无尽的麻烦。

如果你还不太了解什么是范式,可以点击这里:3 normal forms: part1-part2-part3(译者注:原文为yotube视频,由于众所周知的原因国内无法观看,我已将原视频分享到csdn下载区,下载免积分),这个教程将会手把手教你这三个范式。

“范式”是非常重要的准则,但是如果完全一味的遵守,不做丝毫改变的话,会让你经常陷入麻烦之中。当我设计数据库时,我将下面这11条重要的准则牢牢记在心中。

准则1:应用的本质是什么(OLTP还是OLAP)?

(译者注:联机事务处理或联机分析处理,即偏向于增删改查还是偏向于数据分析)

当你开始设计数据库的时候,所要做的第一件事是分析你设计的应用的本质,是事务型呢还是分析型呢。你会发现,许许多多的开发者根本没有考虑自己的应用到底是属于哪种类型,而是全部按照“范式”的准则来设计,然后就碰上了各种各样的性能和定制的问题。正如我所说,有两种应用:基于事务型的和基于分析型的,那么接下来让我们了解一下这两种类型具体是什么。

事务型:这种类型的应用,最终用户对增删改查更为关注,比如,增加、读取、更新和删除记录。对于这种类型的数据库,正式来说我们称呼为OLTP(译者注:Online Transaction Processing,联机事务处理)。

分析型:这种类型的应用,最终用户更关注与对数据的分析、产生报告和对数据的预测等。这种类型的数据库很少执行插入或是更新数据的操作。这种设计的主要意图是以最快的速度从数据库获取数据,并进行分析。对于这种类型的数据库,正式来说我们称呼为OLAP(译者注:Online Analytical Processing,联机分析处理)。

\

换句话说,如果你发现在数据库上进行插入、更新或删除更为重要,那你应该遵循标准的范式来设计,否则应该建立一个扁平非规范的数据库结构。

下图展示了如何在左侧姓名和地址表中运用非规范化设计思想,来创建右侧的不遵守标准范式的扁平的非规范数据结构。

\

准则2:将你的数据划分成若干逻辑片段,让生活更美好

这条准则实际上就是第一范式。违背了这条准则的一个明显特征是,你的查询语句中用了一大堆字符串解析函数,如substring、charindex等。如果的却是这样,那么你需要应用一下这条准则。

举个例子,下图表中有个字段是“Student Name”,如果你想要查询名字中带有"Koirala"而不带有"Harisingh"的学生,你可以想象到时候你写出来的查询语句是什么样的。

所以一个更好的方案是将这个字段分解成更详细的逻辑片段,这样我们就能写出更干净,也更完美的查询语句了。

\

准则3:不要过度使用准则2

开发人员们都是聪明人。如果你告诉了他们一个门路,那么他们就总是使用这个方法。准则2用过头会导致一些你根本不想要的结果。但是准则2本身是非常有用的。当你想着"把这玩意儿拆了"的时候,暂停一下,问问你自己,真有必要拆吗?正如我刚才所说,拆分必须是逻辑性的。

举个例子,你可以看到下图中有个电话号码的字段,你几乎不会对号码的ISD(International Subscriber Dialing,国际订户拨号)分别进行管理(除非哪个项目里真有这个需求),所以就这么把号码放着显然更明智。要是你真的把它们拆了,那到时候你就得面对一大堆的"拆分后遗症"了。

\

准则4:冗余的不统一数据是你最大的敌人

小心冗余数据,并重构它们。我并不担心冗余数据会占用很多磁盘空间,我所担心的是这些冗余数据所造成的困惑与混乱。

比如说,在下图中,你会发现“5th Standard”和“Fifth standard”是一个意思,只不过描述的形式略微不同。你可能会解释说,这些数据是之前有人乱录入的,而且还没有经过验证。当你打算导出一个报告的时候,对于这个字段将产生两份不一样的报告,当用户看到这样的报告,他们恐怕就要在风中凌乱了。

\

一个解决办法就是,把这些数据移到一个新表中,然后原来的表以引用的方式使用这些数据。下图中你可以看到,我创建了一个新的叫做"Standards"的表,然后用一个外键将这两个表连接起来。

\

准则5:小心那些用分隔符分开的数据

第一范式的第二条内容规定了一个位置上不能存多个值。下图就是一个存了多个值的例子。仔细观察"Syllabus"字段就会发现,我们塞了太多的数据到这个字段中了。这种字段我们成为"重复组",如果我们要操作这些数据,不仅查询语句会写的很复杂(且不论对错),而且我很怀疑这种查询的效率。

\

这种某些列里塞了很多数据的字段,要特别小心的对待,一个比较好的解决办法是:将这些字段移到不同的表中,然后将它们用外键相连,以便于从逻辑和操作上更好的进行管理。

\

我们需要遵守第一范式的第二条规定:一个位置不能存储多个值。从上图中可以看到,我建立了一个独立的"syllabus"表,然后与主表建立了多对多的关联。

用这种方法的话,主表中的"syllabus"字段不再塞入一大堆用分隔符分开的数据了。逻辑上易于理解,操作性也更强。

准则6:小心部分依赖

\

小心那些部分依赖于主键的字段,例如上图中的主键是Roll Number和Standard。现在来看看“syllabus”,这个字段与standard字段相关联,而不直接与Student(“Roll Number”字段)相关联。

“syllabus”字段与学生正在学习的"standard"字段相关联,而没有直接和学生关联。那么明天我想要更新“syllabus”的时候,我就必须把所有与之相关的"Student"字段也更新掉。老兄,这是个辛苦的体力活,而且还毫无逻辑!所以更有意义的做法是将"syllabus"字段单独拉出来然后与"Standard"通过外键关联。

你可以看到我是如何将"syllabus"字段拉出来然后与“Standards”相联系。

这条准则其实就是第二范式本身:所有的属性必须做到全部依赖,不应该有字段是部分依赖主键的。

准则7:仔细地选择派生列

\

如果你设计的是OLTP型数据库,即事务型数据库,避免派生列将会是很明智的,除非对这一块内容的性能有高要求。但是对于需要大量求和与计算的OLAP数据库,即分析型数据库,这些派生列就显得很有必要而且能使数据库性能更加优越。

上图中你可以看到,Average依赖Total Marks和Total Subject来计算,这就是数据冗余的表现之一。所以碰到这种派生于其他列的字段,要好好想一想,这个字段真的需要吗?

这条准则正如第三范式所说:字段不能依赖于任何非主键字段。我个人认为不要盲目遵循第三范式,要视情况而定。存在冗余的数据并不总是坏事。如果这些冗余数据是通过计算得来的,看情况来决定要不要遵守第三范式。

准则8:如果性能才是关键,那就不要非常严格地避免冗余数据

\

不要把"避免一切冗余数据"当成一条死命令。如果对性能的要求很高,就考虑一下非标准化吧。遵守标准的话,你经常需要使用join命令来连接很多个表格,但在非标准化中,通过设置一些冗余信息,就没那么多join命令了,所以性能会好得多。

准则9:多维度的数据是一种完全不同的野兽

使用OLAP(分析型)数据库的项目主要处理的是多维数据。举例来说的话你可以看一下下图,你想要得到每个国家的销量,每个顾客的销量和其他数据。简单来说,你所关注的销量是三个维度数据的交集。

\

这种情况下,设计成一个维度将会更好。简单来说,你可以建立一个拥有"sales amount"字段的销量表(它为中心表),然后设置一些外键来和其他的一维表相关联。

\

\

准则10:集中化键值表的设计

我经常会碰到键值表。键值表的意思是,它存储着键和和与这个键相对应的数据(译者注:就像数据结构中的map的用法一样,是一种结构相当简单的表)。举例来说,下表你可以看到有一个Currency 表和Country表,仔细观察就会发现,实际上这两张表中只有一个键和一个对应值而已。

\

对于这种类型的数据表,创建一个集中化的表然后设立一个"Type"字段来区分。这会使你的数据库工作的更好。

准则11:对于多级数据要引用自身的主键,或是设立外键

我也会经常会碰到多集数据的情况,考虑一个多级的销售方案,一个销售员旗下可以有很多个销售员。在这种情况下,引用自身的主键或是设立外键都会帮助你达到想要的效果。

\

这篇文章并不是让你不要遵守标准范式,而是让你不要盲目遵守,你要首先考虑的是项目的属性和你要处理什么类型的数据。

\

下面是一个用简单的学校表来手把手解释三个标准范式的视频(译者注:与上文中的“3 normal forms”为同一个视频,下载过的读者可不必重复下载)

SQL Server -- Can you explain First,Second and Third normal form in SQL server [part1]

SQL Server -- Can you explain First,Second and Third normal form in SQL server [part2]

SQL Server -- Can you explain First,Second and Third normal form in SQL server [part3]

(全文完)

原文来自:http://www.codeproject.com/Articles/359654/11-important-database-designing-rules-which-I-foll

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
MySQL은 sqlite와 어떻게 다릅니 까?MySQL은 sqlite와 어떻게 다릅니 까?Apr 24, 2025 am 12:12 AM

MySQL과 Sqlite의 주요 차이점은 설계 개념 및 사용 시나리오입니다. 1. MySQL은 대규모 응용 프로그램 및 엔터프라이즈 수준의 솔루션에 적합하며 고성능 및 동시성을 지원합니다. 2. SQLITE는 모바일 애플리케이션 및 데스크탑 소프트웨어에 적합하며 가볍고 내부질이 쉽습니다.

MySQL의 색인이란 무엇이며 성능을 어떻게 향상 시키는가?MySQL의 색인이란 무엇이며 성능을 어떻게 향상 시키는가?Apr 24, 2025 am 12:09 AM

MySQL의 인덱스는 데이터 검색 속도를 높이는 데 사용되는 데이터베이스 테이블에서 하나 이상의 열의 주문 구조입니다. 1) 인덱스는 스캔 한 데이터의 양을 줄임으로써 쿼리 속도를 향상시킵니다. 2) B-Tree Index는 균형 잡힌 트리 구조를 사용하여 범위 쿼리 및 정렬에 적합합니다. 3) CreateIndex 문을 사용하여 CreateIndexIdx_customer_idonorders (customer_id)와 같은 인덱스를 작성하십시오. 4) Composite Indexes는 CreateIndexIdx_customer_orderOders (Customer_id, Order_Date)와 같은 다중 열 쿼리를 최적화 할 수 있습니다. 5) 설명을 사용하여 쿼리 계획을 분석하고 피하십시오

MySQL에서 트랜잭션을 사용하여 데이터 일관성을 보장하는 방법을 설명하십시오.MySQL에서 트랜잭션을 사용하여 데이터 일관성을 보장하는 방법을 설명하십시오.Apr 24, 2025 am 12:09 AM

MySQL에서 트랜잭션을 사용하면 데이터 일관성이 보장됩니다. 1) STARTTRANSACTION을 통해 트랜잭션을 시작한 다음 SQL 작업을 실행하고 커밋 또는 롤백으로 제출하십시오. 2) SavePoint를 사용하여 부분 롤백을 허용하는 저장 지점을 설정하십시오. 3) 성능 최적화 제안에는 트랜잭션 시간 단축, 대규모 쿼리 방지 및 격리 수준을 합리적으로 사용하는 것이 포함됩니다.

MySQL을 통해 어떤 시나리오에서 PostgreSQL을 선택할 수 있습니까?MySQL을 통해 어떤 시나리오에서 PostgreSQL을 선택할 수 있습니까?Apr 24, 2025 am 12:07 AM

MySQL 대신 PostgreSQL을 선택한 시나리오에는 다음이 포함됩니다. 1) 복잡한 쿼리 및 고급 SQL 기능, 2) 엄격한 데이터 무결성 및 산 준수, 3) 고급 공간 기능이 필요하며 4) 큰 데이터 세트를 처리 할 때 고성능이 필요합니다. PostgreSQL은 이러한 측면에서 잘 수행되며 복잡한 데이터 처리 및 높은 데이터 무결성이 필요한 프로젝트에 적합합니다.

MySQL 데이터베이스를 어떻게 보호 할 수 있습니까?MySQL 데이터베이스를 어떻게 보호 할 수 있습니까?Apr 24, 2025 am 12:04 AM

MySQL 데이터베이스의 보안은 다음 조치를 통해 달성 할 수 있습니다. 1. 사용자 권한 관리 : CreateUser 및 Grant 명령을 통한 액세스 권한을 엄격히 제어합니다. 2. 암호화 된 전송 : 데이터 전송 보안을 보장하기 위해 SSL/TLS를 구성합니다. 3. 데이터베이스 백업 및 복구 : MySQLDump 또는 MySQLPump를 사용하여 정기적으로 백업 데이터를 사용하십시오. 4. 고급 보안 정책 : 방화벽을 사용하여 액세스를 제한하고 감사 로깅 작업을 가능하게합니다. 5. 성능 최적화 및 모범 사례 : 인덱싱 및 쿼리 최적화 및 정기 유지 보수를 통한 안전 및 성능을 모두 고려하십시오.

MySQL 성능을 모니터링하는 데 사용할 수있는 몇 가지 도구는 무엇입니까?MySQL 성능을 모니터링하는 데 사용할 수있는 몇 가지 도구는 무엇입니까?Apr 23, 2025 am 12:21 AM

MySQL 성능을 효과적으로 모니터링하는 방법은 무엇입니까? Mysqladmin, Showglobalstatus, Perconamonitoring and Management (PMM) 및 MySQL Enterprisemonitor와 같은 도구를 사용하십시오. 1. MySQLADMIN을 사용하여 연결 수를보십시오. 2. showglobalstatus를 사용하여 쿼리 번호를보십시오. 3.pmm은 자세한 성능 데이터 및 그래픽 인터페이스를 제공합니다. 4. MySQLENTERPRISOMITOR는 풍부한 모니터링 기능 및 경보 메커니즘을 제공합니다.

MySQL은 SQL Server와 어떻게 다릅니 까?MySQL은 SQL Server와 어떻게 다릅니 까?Apr 23, 2025 am 12:20 AM

MySQL과 SqlServer의 차이점은 1) MySQL은 오픈 소스이며 웹 및 임베디드 시스템에 적합합니다. 2) SQLServer는 Microsoft의 상용 제품이며 엔터프라이즈 수준 애플리케이션에 적합합니다. 스토리지 엔진의 두 가지, 성능 최적화 및 응용 시나리오에는 상당한 차이가 있습니다. 선택할 때는 프로젝트 규모와 향후 확장 성을 고려해야합니다.

MySQL을 통해 어떤 시나리오에서 SQL Server를 선택할 수 있습니까?MySQL을 통해 어떤 시나리오에서 SQL Server를 선택할 수 있습니까?Apr 23, 2025 am 12:20 AM

고 가용성, 고급 보안 및 우수한 통합이 필요한 엔터프라이즈 수준의 응용 프로그램 시나리오에서는 MySQL 대신 SQLServer를 선택해야합니다. 1) SQLServer는 고 가용성 및 고급 보안과 같은 엔터프라이즈 수준의 기능을 제공합니다. 2) VisualStudio 및 Powerbi와 같은 Microsoft Ecosystems와 밀접하게 통합되어 있습니다. 3) SQLSERVER는 성능 최적화에서 우수한 성능을 발휘하며 메모리 최적화 된 테이블 및 열 스토리지 인덱스를 지원합니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

VSCode Windows 64비트 다운로드

VSCode Windows 64비트 다운로드

Microsoft에서 출시한 강력한 무료 IDE 편집기

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경

맨티스BT

맨티스BT

Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

mPDF

mPDF

mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.