标题：数据建模
简介
数据建模指的是对现实世界各类数据的抽象组织，确定数据库需管辖的范围、数据的组织形式等直至转化成现实的数据库。 将经过系统分析后抽象出来的概念模型转化为物理模型后,在visio或erwin等工具建立数据库实体以及各实体之间关系的过程.(实体一般是表)
分类
1、使用计算机描述一个系统的行为。例如，没电子表格程序可以用来处理财务数据，代表公司的行为；开发商业计划；评估公司经营改变可能造成的影响。请参阅 simulation，spreadsheet program。【英】The use of computersto describe the behavior of a system. Spreadsheet programs, for example, can be used to manipulate financial data,representing the activity of a company; to develop business projections; or to evaluate the impact of proposedchanges on the company’s operations. 
2、使用计算机以数学方法描述物体和它们之间的空间关系。例如，计算机辅助设计 (CAD) 程序可在屏幕上生成物体，使用方程式产生直线和形状，依据它们相互之间及与所在的二维或三维空间的关系精确放置。
3、应用程序和数据建模是为应用程序确定、记录和实现数据和进程要求的过程。这包括查看现有的数据模型和进程，以确定它们是否可被重复使用，并创建新数据模型和进程，以满足应用程序的独特要求。
主要活动
建模过程中的主要活动包括： 
确定数据及其相关过程（如实地销售人员需要查看在线产品目录并提交新客户订单）。 
定义数据（如数据类型、大小和默认值）。 
确保数据的完整性（使用业务规则和验证检查）。 
定义操作过程（如安全检查和备份）。 
选择数据存储技术（如关系、分层或索引存储技术）。 
一定要知道建模通常会以意想不到的方式涉及公司的管理。例如，当对哪些数据元素应由哪些组织来维护有新的见解时，数据所有权（以及数据维护、准确性和及时性的隐含责任）通常会遭到质疑。数据设计常常促使公司认识到企业数据系统是如何相互依存的，并且鼓励公司抓住协调后的数据规划所带来的效率提高、成本节约和战略性机遇。
在结束建模时，您已经完全定义了应用程序的要求，确定了可能被其他企业级应用程序重复使用的数据和服务，并为将来扩展奠定了强有力的基础。
如何进行数据建模
概念建模
如果你在Google或者百度上搜索数据建模，相信可以搜索出很多关于数据建模的文章，但是你会发现其中绝大部分是理论、方法论、概念等，读起来很学院派，感觉很有道理，但是心里不由在想，我到底该怎么进行数据建模呢？
笔者自06年投身到IT行业中，主要活动在数据库层，数据建模，数据库设计以及数据库开发，尤其是在数据仓库领域，期间用到的数据库主要是SQL Server和MySQL；目前正在给国内一家客户做内部IT系统的数据建模工作，主要负责数据库（MySQL）设计。自己也读过一些数据库设计方面的书籍，在各大技术类网站上也拜读过很多神贴，大大小小的项目的数据库设计工作也参与过几十个，今天有幸在TechTarget数据库网站上和大家分享自己对数据建模的观点，任何不同观点或者反对意见，欢迎大家发送到我的邮箱；就像数据库设计一样，不可能一步到位，都是一个迭代的过程，在讨论甚至是争论中成长！
数据建模大致分为三个阶段，概念建模阶段，逻辑建模阶段和物理建模阶段。其中概念建模和逻辑建模阶段与数据库厂商毫无关系，换言之，与MySQL，SQL Server，Oracle没有关系。物理建模阶段和数据库厂商存在很大的联系，因为不同厂商对同一功能的支持方式不同，如高可用性，读写分离，甚至是索引，分区等。
概念建模阶段
实际工作中，在概念建模阶段，主要做三件事：
1. 客户交流
2. 理解需求
3. 形成实体
这也是一个迭代，如果先有需求，尽量去理解需求，明白当前项目或者软件需要完成什么，不明白或者不确定的地方和客户及时交流，和客户double confirm过的需求，落实到实体（Package）；但是好多时候我们需要通过先和客户交流，进而将交流结果落实到需求，之后进一步具体到实体；本文可能会涉及到一些来自于EA（Enterprise Architect 7.1）建模术语，（EA中将每个实体视为一个Package）。这里并不对各种建模工具进行比较，如Visio，EA，PowerDesigner， ERWin等；其实作为员工的我们选择性很少，公司有哪个产品的Licence，我们就用哪个吧。
举例说明：在一个B2C电子商务网站中，这样的需求再普通不过了：客户可以在该网站上自由进行购物！我们就以这个简单例子，对其进行细分，来讲解整个数据建模的过程，通过上面这句话，我们可以得出三个实体：客户，网站，商品；就像Scrum（敏捷开发框架的一种）中倡导的一样每个Sprint，都要产出确确实实的东西，OK，概念建模阶段，我们就要产出实体。客户和商品（我们将网站这个实体扔掉，不需要它。）
在创建这两个实体（Package）的时候，我们记得要讲对需求的理解，以及业务规则，作为Notes添加到Package中，这些信息将来会成为数据字典中非常重要的一部分，也就是所谓的元数据。BTW，EA或者其他建模工具应该都可以自动生成数据字典，只不过最终生成的格式可能不太一样。如在Customer这个Package的Notes上，我们可以这样写，用户都要通过填写个人基本信息以及一个邮箱来注册账户，之后使用这个邮箱作为登录帐号登录系统进行交易。
在概念建模阶段，我们只需要关注实体即可，不用关注任何实现细节。很多人都希望在这个阶段把具体表结构，索引，约束，甚至是存储过程都想好，没必要！！因为这些东西使我们在物理建模阶段需要考虑的东西，这个时候考虑还为时尚早。可能有的人在这个阶段担心会不会丢掉或者漏掉一些实体?也不用担心，现在好多公司都在采用Scrum的开发模式，只要你当前抽象出来的实体满足当前的User Story，或者当前的User Story里面的实体，你都抽象出来了，就可以了！如果你再说，我们User Story太大，实体太多，不容易抽象，那就真没办法了，建议你们的团队重新开Sprint 计划会议。
逻辑建模
逻辑建模阶段
对实体进行细化，细化成具体的表，同时丰富表结构。这个阶段的产物是，可以在数据库中生成的具体表及其他数据库对象（包括，主键，外键，属性列，索引，约束甚至是视图以及存储过程）。我在实际项目中，除了主外键之外，其他的数据库对象我都实在物理建模阶段建立，因为其他数据库对象更贴近于开发，需要结合开发一起进行。如约束，我们可以在web page上做JavaScript约束，也可以在业务逻辑层做，也可以在数据库中做，在哪里做，要结合实际需求，性能以及安全性而定。
针对Customer这个实体以及我们对需求的理解，我们可以得出以下几个表的结构，用户基本信息表（User），登录账户表（Account），评论表（Commnets,用户可能会对产品进行评价），当然这个案例中我们还会有更多的表，如用户需要自己上传头像（图片），我们要有Picture表。
针对产品实体，我们需要构建产品基本信息表（Product），通常情况下，我们产品会有自己的产品大类（ProductCategory）甚至产品小类（ProductSubCategory），某些产品会因为节假日等原因进行打折，因为为了得到更好的Performance我们会创建相应ProductDiscount表，一个产品会有多张图片，因此产品图片表（ProductPicture）以及产品图片关系表（ProductPictureRelationship），（当然我们也可以只设计一张Picture表，用来存放所有图片，用户，产品以及其他）有人说产品和图片是一对多的关系，不需要创建一个关系表啊?是的，我认为只要不是一对一的关系，我都希望创建一个关系表来关联两个实体。这样带来的好处，一是可读性更好，实现了实体和表一一对应的关系，二是易于维护，我们只需要维护一个关系表即可，只有两列（ProductID和PictureID），而不是去维护一个Picture表。
客户进行交易，即要和商品发生关系，我们需要Transaction表，一个客户会买一个或者多个商品，因为一笔Transaction会涉及一个或多个Products，因此一个Transaction和ProductDiscount之间的关系（ProductDiscount和Product是一一对应的关系）需要创建，我们称其为Item表，里面保存TransactionID以及这笔涉及到的ProductDiscountID（s），这里插一句，好多系统都需要有审计功能，如某个产品历年来的打折情况以及与之对应的销售情况，我们这里暂不考虑审计方面的东西。
就这样，我们根据需求我们确定下来具体需要哪些表，进一步丰富每一个表属性（Column），当然这里面会涉及主键的选取，或者是使用代理键（Surrogate Key），外键的关联，约束的设置等细节，这里笔者认为只要能把每个实体属性（Column）落实下来就是很不错了，因为随着项目的开展，很多表的Column都会有相应的改动。至于其他细节，不同数据库厂商，具体实现细节不尽相同。关于主键的选取都说一句，有的人喜欢所有的表都用自增长ID作为主键，而有的人希望找到唯一能标识当前记录的一个属性或者多个属性作为主键；自增长ID作为代理主键，对于将来以多个类似当前Transaction System作为数据源，构建数据仓库的时候，这些自增长ID主键会是一个麻烦（多个系统中，相同表存在大量主键重复）；使用一个属性或多个属性作为作为主键，不管主键是可编辑的，读写效率是我们必须考虑得。所以并没有一个放之四海而皆准的原则，笔者只是给大家推荐一些考虑的因素。
物理建模
物理建模阶段
EA可以将在逻辑建模阶段创建的各种数据库对象生成为相应的SQL代码，运行来创建相应具体数据库对象（大多数建模工具都可以自动生成DDL SQL代码）。但是这个阶段我们不仅仅创建数据库对象，针对业务需求，我们也可能做如数据拆分（水平或垂直拆分），如B2B网站，我们可以将商家和一般用户放在同一张表中，但是针对PERFORMANCE考虑，我们可以将其分为两站表；随业务量的上升，Transaction表越来越大，整个系统越来越慢，这个时候我们可以考虑数据拆分，甚至是读写分离（即实现MASTER-SLAVE模式，MYSQL/SQLSERVER可以使用Replication，当然不同存储引擎采用不同的方案），这个阶段也会涉及到集群的事情，如果你是架构师或者数据建模师，这个时候你可以跟DBA说，Alright,I am done with it,now is your show time.
相信大家都知道范式，更有好多人把3NF奉为经典，3NF确实很好，但是3NF是几十年前提出来的，那个时候的数据量以及访问频率和目前完全不是一个数量级的；因此我们绝对不能一味地遵守3NF；在整个数据建模过程中，在保证数据结构清晰的前提下，尽量提高性能才是我们关注的要点，因此笔者大力倡导数据适当冗余!
上面笔者是结合一些实际例子表达自己对数据建模的观点，希望对读着有用。在数据建模过程中，不要希望一步到位将数据库设计完整，笔者不管是针对data warehouse还是Transactional Database设计，从来没有过一次成功的经历。随着项目的进行，客户和开发团队对业务知识与日增长，因此原来的设计也在不断完善中。毕竟，数据建模或者设计数据库不是我们的最终目的，我们需要的是一个健壮，性能优越，易扩展，易使用的软件!