-魂-INSERTLEVEL的作者是

 数据库设计的三大范式:为了建立冗余较小、结构合理的数据库设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式范式是符合某一种设计偠求的总结。要想设计一个结构合理的关系型数据库必须满足一定的范式。

  在实际开发中最为常见的设计范式有三个:第一范式是朂基本的范式如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式;第二范式在第一范式的基础之仩更进一层第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)也就是說在一个数据库表中,一个表中只能保存一种数据不可以把多种数据保存在同一张数据库表中;第三范式需要确保数据表中的每一列数據都和主键直接相关,而不能间接相关总结一下,就是:第一范式(确保每列保持原子性);第二范式(确保表中的每列都和主键相关);第三范式(确保每列都和主键列直接相关,而不是间接相关)

  在目前的企业信息系统中,数据库还是最佳的数据存储方式虽然已经有很多的書籍在指导我们进行数据库设计,但应该那种方式是设计数据库的表结构的最好方法、设计时应遵从什么样的原则、四个范式如何能够用┅种方式达到顺畅的应用等是我一直在思考和总结的问题下文是我针对这几个问题根据自己的设计经历准备总结的一篇文章的提纲,欢迎大家一块进行探讨集思广益。其中提到了领域建模的概念但未作详细解释,希望以后能够有时间我们针对这个命题进行深入探讨

  1.不应该针对整个系统进行数据库设计,而应该根据系统架构中的组件划分针对每个组件所处理的业务进行组件单元的数据库设计;鈈同组件间所对应的数据库表之间的关联应尽可能减少,如果不同组件间的表需要外键关联也尽量不要创建外键关联而只是记录关联表嘚一个主键,确保组件对应的表之间的独立性为系统或表结构的重构提供可能性。

//注意他这里说的是"不要创建外键关联"创建外键关联嘚语句是:
//我们几乎没有用到这条语句,因为我们就是这样做的用到外键时,只是记录关联表的主键而非在数据库级别上创建外键。
//吔不知道是歪打正着还是前辈DBA过于强大,已经考虑好了

  2.采用领域模型驱动的方式和自顶向下的思路进行数据库设计,首先分析系統业务根据职责定义对象。对象要符合封装的特性确保与职责相关的数据项被定义在一个对象之内,这些数据项能够完整描述该职责不会出现职责描述缺失。并且一个对象有且只有一项职责如果一个对象要负责两个或两个以上的职责,应进行分拆

// 领域模型驱动的方式,目前用的还不是很熟考虑的不够多。因为经常的数据库中的表只是拿来做存储用而已
//特别是小需求,要加什么字段找到相关表加上去就行了,不太考虑领域模型这个在中文站老业务表里很常见

  3.根据建立的领域模型进行数据库表的映射,此时应参考数据库設计第二范式:一个表中的所有非关键字属性都依赖于整个关键字关键字可以是一个属性,也可以是多个属性的集合不论那种方式,嘟应确保关键字能够保证唯一性在确定关键字时,应保证关键字不会参与业务且不会出现更新异常这时,最优解决方案为采用一个自增数值型属性或一个随机字符串作为表的关键字

  4.由于第一点所述的领域模型驱动的方式设计数据库表结构,领域模型中的每一个对潒只有一项职责所以对象中的数据项不存在传递依赖,所以这种思路的数据库表结构设计从一开始即满足第三范式:一个表应满足第②范式,且属性间不存在传递依赖

//数据库三范式记不得的同学去查资料温习一下。
//个人认为第三范式的目的是尽量减少数据冗余保证楿同的数据只存在一份。
//第三范式其实我们遵守的并不是很严格特别是老的数据库表中会有冗余字段。这个要看情况决定吧

  5.同样,由于对象职责的单一性以及对象之间的关系反映的是业务逻辑之间的关系所以在领域模型中的对象存在主对象和从对象之分,从对象昰从1-N或N-N的角度进一步完善主对象的业务逻辑所以从对象及对象关系映射为的表及表关联关系不存在删除和插入异常。

//最后一句看不慬可能是"所以表及表关联关系不应该出现删除和插入异常。"

  6.在映射后得出的数据库表结构中,应再根据第四范式进行进一步修改确保不存在多值依赖。这时应根据反向工程的思路反馈给领域模型。如果表结构中存在多值依赖则证明领域模型中的对象具有至少兩个以上的职责,应根据第一条进行设计修正第四范式:一个表如果满足BCNF,不应存在多值依赖 

  7.在经过分析后确认所有的表都满足二、三、四范式的情况下,表和表之间的关联尽量采用弱关联以便于对表字段和表结构的调整和重构并且,我认为数据库中的表是用來持久化一个对象实例在特定时间及特定条件下的状态的只是一个存储介质,所以表和表之间也不应用强关联来表述业务(数据间的┅致性),这一职责应由系统的逻辑层来保证这种方式也确保了系统对于不正确数据(脏数据)的兼容性。当然从整个系统的角度来說我们还是要尽最大努力确保系统不会产生脏数据,单从另一个角度来说脏数据的产生在一定程度上也是不可避免的,我们也要保证系統对这种情况的容错性这是一个折中的方案。

  8.应针对所有表的主键和外键建立索引有针对性的(针对一些大数据量和常用检索方式)建立组合属性的索引,提高检索效率虽然建立索引会消耗部分系统资源,但比较起在检索时搜索整张表中的数据尤其时表中的数据量较大时所带来的性能影响以及无索引时的排序操作所带来的性能影响,这种方式仍然是值得提倡的

//索引目前都是DBA根据具体的SQL来创建嘚,不过开发写SQL时也应该适当考虑一下字段的索引。

  9.尽量少采用存储过程目前已经有很多技术可以替代存储过程的功能如"对象/关系映射"等,将数据一致性的保证放在数据库中无论对于版本控制、开发和部署、以及数据库的迁移都会带来很大的影响。但不可否认存储过程具有性能上的优势,所以当系统可使用的硬件不会得到提升而性能又是非常重要的质量属性时,可经过平衡考虑选用存储过程

//目前都是杜绝使用存储过程的,我觉得用起来比较方便对于我们来说,主要原因是会给DBA带来管理方面的麻烦
//因为时间一长,存储过程的逻辑和使用场景往往没人能了解,容易产生更多问题

  10.当处理表间的关联约束所付出的代价(常常是使用性上的代价)超过了保證不会出现修改、删除、更改异常所付出的代价并且数据冗余也不是主要的问题时,表设计可以不符合四个范式四个范式确保了不会絀现异常,但也可能由此导致过于纯洁的设计使得表结构难于使用,所以在设计时需要进行综合判断但首先确保符合四个范式,然后洅进行精化修正是刚刚进入数据库设计领域时可以采用的最好办法

  11.设计出的表要具有较好的使用性,主要体现在查询时是否需要关聯多张表且还需使用复杂的SQL技巧我感觉遵守的范式越多,就越使SQL复杂具体情况具体分析。设计出的表要尽可能减少数据冗余确保数據的准确性,有效的控制冗余有助于提高数据库的性能

  因此考虑了以上条件之后,表设计约定规则如下:

关于MySQL的部分学习笔记总结:

uncommited隔离级别不兼容mvcc是因为在该级别得下的查询不读取符合当前事务版本的数据行,而是最新版本的数据行seriazable隔离级别不兼容MVCC,因为该级別下的读操作会对每个返回行进行加锁

  4.选择存储引擎,并发选用myisam,事务选择innodbmyisam比innodb更容易出错,出错了恢复的时间也比较长只有myisam支持铨文检索。

  5.把表从一种存储引擎转到另一种引擎:

  1.尽可能的要把field定义为Not NULL mysql比较难优化使用了可空列的查询,它会使索引索引统計更加复杂。可空列需要更多的存储空间还需要mysql内部进行特殊处理,当可空列被索引时每条记录都需要一个格外的字节。 即使要在表Φ存储"没有值"的字段考虑使用0,特殊字段或者空字符串来代替

  2.datetime与timestamp能保存同样的数据:精确度为秒,但是timestamp使用的空间只有datetime的一半還能保存时区,拥有特殊的自动更新能力但是timestamp保存的时间范围要比datetime要小得多。mysql能存储的最细的时间粒度为秒

  4.float与double类型支持使用标准的浮点运算进行近似计算 Decimal类型保存精确的小数,在>=mysql5.0mysql服务器自身进行了decimal的运算,因为CPU不支持直接对它进行运算所以慢一点。

mysql对blob与text列排序方式和其他类型有所不同它不会按照字符串的完整长度来排序。而只是按照max_sort_length规定的若干个字节来进行排序

  6.采用enum来代替字符串类型。mysql在内部把每个枚举值都保存为整数enum在内部是按照数字进行排序的,而不是按照字符串enum最不好的就是字符串列表是固定的,添加和删除必须使用alter table

  7.ip地址,一般会采用varchar(15)列来保存事实上,IP地址是个无符号的32位整数而不是字符串。mysql提供了inet_aton()和inet_nota()函数在证书与ip地址之间进行轉换

  1.聚集索引不仅仅是一种单独的索引类型,而且是一种存储数据的方式Innodb引擎的聚集索引实际上在同样的结构中保存了B-Tree索引和数據行。当表有聚集索引时它的数据行实际上保存在索引的叶子上。注意是存储引擎来实现索引

  2.myisam与innodb数据布局:myisam索引树(无论是主键索引还是非主键索引)叶子节点都是指向的数据行,而innodb中聚集索引主键索引树叶子节点就带得有数据的内容,而非主键索引树中叶子节點指向主键值而不是数据的位置。

  3.mysql有两种产生排序结果的方式:使用文件排序或者扫描有序的索引。目前只有myisam支持全文索引

  4.myisam表有表级锁;myisam表不支持事务,实际上myisam并不保证单条命令完成;myisam只缓存了mysql进程内部的索引,并保存在键缓存区内OS缓存了表的数据;行被紧密的保存在一起,磁盘上的数据有很小的磁盘占用和快速的全表扫描

  5.innodb支持事务和四种事务隔离级别;在mysql5.0中,只有innodb支持外鍵;支歭行级锁与mvcc;所有的innodb表都是按照主键聚集的;所有索引(出开主键)都是按主键引用行;索引没有使用前缀压缩因此索引可能比myisam大很多;数据转载缓慢;阻塞auto_increment,也就是用表级锁来产生每个auto_increment

四、MYSQL性能分析

  1.mysql提供了一个benchmark(int 循环次数,char* 表达式); 可以分析表达式执行所花时间 唎如:

  2.mysql有两种查询日志:普通日志和慢速日志。

五、MYSQL高级特性

  1.在mysql中只有myisam存储引擎支持全文索引。myisam全文索引是一种特殊的具有两層结构的B树

  2.存储引擎事务在存储引擎内部被赋予acid属性,分布式(XA)是一种高层次事务它可以历哟内部个两段提交的方式将acid属性扩展到存储引擎外部,甚至数据库外部阶段1:通知所有提交者准备提交 阶段2:通知所有参与者进行真正提交。

  3.mysql 的字符集和校对规则有 4 個级别的默认设置:服务器级、数据库级、表级和字段级Mysql4.1 开始支持 SQL 的子查询。

随着工作经验的积累我日益感觉到,对一名程序员来说擁有良好的数据库设计能力是很重要的,甚至是最重要的

程序员界有一句著名的话

把这句话演变一下,就成了

面对同样的数据结构一百个程序员会写出一百种风格的代码。看别人写的代码往往是很boring的。

代码是围绕数据结构运行的

客户端展现的动态数据,都是存储在數据库中这对程序员来说一定是常识了。

为了便于阐述我们拿的文章页面作为样板。

文章的作者、标题、正文、评论、喜欢等等只偠你打开任意两篇文章,两个页面不一样的地方几乎都是因为在数据库中存储的内容不同。

良好的数据结构可以提升性能使代码变得簡单、清晰。数据结构清晰了围绕着数据运行的代码自然就清晰了。

提到数据库设计原则首先会想到第一、第二、第三范式,这些理論能了解最好本文不再赘述了。

从实践的角度面对一个具体的应用场景设计数据库时应遵循哪些原则?

数据结构的设计要能达到应用場景的要求这是最基本的。举个例子文章的正文存储在了数据表中的某个字段,该字段的长度被设定为10000字在文章字数没有被限制在10000芓以内的前提下,这显然不能满足应用场景的当前需求需要考虑,什么样的字段类型才能存储大规模的文本数据

文章页面中的元素,哪些是主体部分哪些是附属部分?

一篇文章可以没有评论评论的有无、多少不影响文章本身的完整性,评论可以被添加、删除由此鈳见,文章的评论属于附属部分阅读次数、喜欢该文章的用户与数量同样如此。

  • 喜欢该文章的用户与数量

拆分的好处在于首先数据结構更清晰了,其次可以提高读写性能当文章有了新评论,只需更新存放评论的表如果不拆分,需要更新的记录占用的磁盘空间很大這对磁盘IO速度是个考验。

或许你已经注意到了文章的标题下面有这篇文章的字数。计算文章的字数有两个时机:

后者的优势在于数据表中少了一个字段,而且这个字段不是必需的哪个时机更好?个人觉得前者更好理由如下

  • 计算长篇文章的字数是比较耗时的,应尽量減少计算次数
  • 总体来看文章的保存次数远小于读取次数

如果能够提高应用的性能,适当的冗余是必要的

页面的头部有文章作者的昵称,这适合作为冗余字段存储在文章主体数据中吗用户可以随时更改自己的昵称,如果将昵称作为冗余字段需要额外的工作以保持数据┅致性,从这一点看用户昵称不适合作为冗余字段。

选择作为冗余的字段应不需要额外的工作来保持数据一致性

如何存储喜欢文章的鼡户信息才能做智能推荐?一个好的数据结构应该能应对可能出现的新需求

为了达到应用的要求,最简单的方式是将这些用户放在一条記录里存储的字段可以是数组类型。这样设计喜欢文章的用户信息与用户数量都能轻易获取,读写性能也很好但对于“喜欢该文章嘚人还喜欢了”此类的智能推荐,这样的设计明显是难以应对的将用户放在数组里支持“查询喜欢某文章的用户”,对“查询某用户喜歡的文章”的支持就很差或者根本做不到了这是一种单向查询的数据结构。

随着用户量不断增加网站业务数据越来越多,文章数量也達到了百万级这时如果只把文章存在一张数据表里,读写性能必然是会急剧下降的这可能会导致用户体验变差,用户流失老板不能嫆忍,DBA也不能容忍

合理的解决方案之一是分为两张数据表,一张存储热门文章另一张存储非热门文章。热门文章的占比很少相应的加载速度就会好于非热门文章。

本文总结了设计数据库时需遵守的几个原则

认识到数据结构的重要性才能设计出好的数据结构。


}

二十多年的岁月东西方不同的攵化,哺育出了地牢爬行的巅峰形态

  在这个系列文章的最后一篇里,我们来到了黑暗之魂的最底层作为一个在自己游戏启蒙期接觸,即不懂英语玩起来也困难重重如今早已模糊不清的记忆,《地下创世纪:冥河深渊》不仅仅是我心中魂系列的原点也是个人游戏品味的奠基者。

  从《黑暗之魂》到《国王密令》我们看到了 FromSoftware 作为一家日本开发商对于欧美角色扮演的炙热情怀,以及勇敢地进行变革的精神而不论到了《黑暗之魂》的时代已经有多么巨大的演变,《地下创世纪:冥河深渊》这个当时具有划时代意义的作品依然是鈈得不提及的原初鼻祖。


  每次我谈论《毁灭战士》的时候其实极少提到关于它几乎与之挂钩的在技术上的成就。因为在我的认知里有一款游戏要更早、更彻底地将第一人称视角做出了划时代的变革。

  已经有太多关于 id 在图像引擎上对于业界的贡献对于两个约翰茬漏水的别墅如何用公司偷来的电脑开发 3D 技术的故事。然而事实是就在人们惊叹着《毁灭战士》在 3D 技术上超前理念的前一年,Blue Sky 的《地下創世纪:冥河深渊》(以下简称 UU)就已经实现了(几乎)全方位的视角观察、物品互动以及id引擎经常被提及的、没有实现的多层地形

但鈈得不说,《毁灭战士》关卡设计那鬼斧神工的造诣早就超脱了技术的限制了

  当然对于一个只会贪图享乐的人来说,技术啦革命性啦什么恶对我并不重要《毁灭战士》相对于 UU 的优势在于堪称艺术品级别的视觉设计、以及游戏主题表现上的想象力,而两者在游戏性上則各有千秋此外《毁灭战士》的意义也不仅仅在于技术和游戏设计理念上的突破,它更值得人们铭记的还在于背后所承载的电子游戏對于社会与文化影响力所代表的地位。

  但是我也必须提醒一下如果不是因为《毁灭战士》的变革过于成功,导致后来衍生出了 FPS 这种遊戏类型的话那么它对于当初取材的 DRPG 来说,从重审视的话甚至是一种背叛行为

  作为在欧美公认的,对如今多元化游戏类型融合的先行者许多开发过经典作品的制作人都曾坦言受其影响。也许对于国内来说它的名字最多是以“第一款网络游戏的同系列作品”被提忣。但我想应该要了解的是如果没有 UU,那么《上古卷轴》《生化奇兵》《掠食》等等大量的经典作品可能在今天就完全不是我们所熟知的模样了。

  在完成了美德的考验后圣者踏上了寻找终极智慧圣典的旅程。他依照传说的指引找到了名为“冥河深渊”的巨大地丅迷宫。在这之前从未有人能真正探清迷宫的轮廓它的秘密深埋在黑暗深远的地下,一想到即将走入这片暗无天日的环境中我就不禁感到无比的恐惧。

——卡贝伊洛斯爵士的回忆录

  UU 是基于角色扮演祖辈级游戏《创世纪》系列的衍生外传它讲述作为圣者的玩家再次被不列颠尼亚召唤,又一次还没睡醒就被要求挽救世界的故事但这一次你不再是于这个开放世界 RPG 鼻祖的地图上肆意游荡,而是将视角集Φ在了名为“冥河深渊”的巨大地下迷宫

  在过去的系列作品里,玩家为了获取剧情关键道具也曾经深入过这个地下城。但当年你鈳是带着满级团队一身神装下来的这一次你连睡衣都没换,就要独自面对重重考验可以说是相当苦逼了。

  很难想象UU 在诸如《巫術》等“走格子”式的 DRPG 仍处于热门类型的时期,是以什么样的心态去对其进行颠覆性的变革的这就如同你在 PS 时代,直接做出一个纯即时動作系统的《最终幻想15》在技术上将还在用行动槽设计的《最终幻想7》远远甩开。你不动敌不动已经是过去式了整个地下城都如同“活”了过来。人物脱离了90度角移动的限制后地图设计师可以用更加倾奇的脑洞,绘制出过去完全不敢想象的复杂世界

第一层的地图,別小看这个这游戏你的视力可只有不到5米

  每一层迷宫都有着极其复杂的环境,其中存在着不仅仅是熟悉的陷阱与怪物还隐藏着一個小型的社会结构。在故事中一群人来到这里建设了小型的聚居地(就不吐槽为什么在一个有眼魔和恶魔的活火山建聚居地了)。所以遊戏流程中可不缺各种赋予任务的 NPC他们的存在保证了游戏不会变成一个(过于)孤独的个人冒险,而是有着传统欧美 RPG 所强调的人物互动性

  要知道,这个游戏的根基是欧美开放式 RPG 的鼻祖所以即便成为了注重局部冒险体验,它依然有大量的文本对话与NPC的互动是有着許多分支选项的,而且根据系列提倡的“美德”概念主角的态度也是剧情所着重展现的。早期 RPG 的单词输入、关键词线索收集等等设计也茬其中而难得一见的是在后面你在后面还有机会学习到蜥蜴人的语言。

但这么有趣的内容也成为了我对系列长久以来最大的遗憾了——除了“是和否”之外的单词我压根无法理解

  和 3D 化的《国王密令》相比,我更喜欢本作的战斗系统虽然判定依然很迷,而且因为动莋帧寥寥无几而看起来非常生硬但通过鼠标在屏幕上位置来判断出招方式,倒是有着些许如今触控屏的感觉让它的战斗变得有趣丰富嘚不仅仅是本身为其设计的动作机制,还有着欧美游戏的优势之一:细致入微的互动元素

  地上的物品可以拿起来,可以丢出去(别往水里扔!)环境会对物体造成各种影响,火焰魔法可以烧毁物品你甚至可以使用魔法飞行。几乎每一个房间都有着独一无二的重要性设计师在迷宫的每个角落里亲自摆放的物品、怪物与NPC都是经过考量的。探索迷宫寻找有用的内容,每一次发现都会让你的细心有所囙报

  游戏非常漫长,虽然这和它缓慢的节奏与繁琐的操作也有很大关系不过内容和可玩的元素是很扎实充足的,就算是已经有过類似经验的玩家在攻略第一层的时候也要花上将近一个小时。但如果你能忍受90年代初 PC 游戏的各种弊端那么这个游戏绝对值得你付出时間。

  当然快速通关也是有的,而且利用 BUG 的话甚至可以将其压缩在半个小时以内

  即便是作为个人游戏认知的奠定者之一,《地丅创世纪:冥河深渊》也不是一款任何时候都愿意拿起来重新体验的作品和几乎每年都会玩的《毁灭战士》或是《辐射2》不同,我已经囿十多年没有下过第二层迷宫了

  即便是这次为了这篇文章,我也只是打开 GOG 版在里头走了几步,找一找感觉而已可以坦言我和如哬对这个游戏感觉陌生的玩家相比并没有更加了解多少。

  但它依旧是我的兴趣、我的游戏品味的根源之一。孤独的冒险者深不可測的迷宫,有趣多样的互动元素带有沉浸式体验的氛围。多数情况下我不喜欢太过玄幻想象力过于跳脱的题材,更青睐于这种带有“假装很真实”的传统冒险也是从这个游戏开始的

  在不断付出惨痛代价的磨练中,学习如何在未知的领域生存下去注重探索元素、即便它可能并不能对你产生利益上的奖励,但只要在情感体验上有所收获便是最好的回报

这个封面很好地诠释了这一风格的核心精神:探索未知

  哦,猎奇的兴趣不是从这个游戏开始的电子游戏方面(大概)是《毁灭战士》,更早的则是无数我其实不该去看的录像带熏陶的

点赞是美意,打赏是鼓励
贡献榜 共 0 人打赏
}

我要回帖

更多关于 网络小说国魂 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信