好的设计让你上天堂,烂的设计让你下地狱。
如果公司有专门的 DBA,後端工程师就可以把心力放在资料逻辑的处理上;但笔者询问周围的朋友,似乎有不少公司都是让後端工程师兼任 DBA...
笔者在这块也并非专家,主要是分享自己实作中会注意的基础细节,避免犯下一些原则性错误
。
设计资料库时会考量哪些点?
回答问题所需具备的知识
衍伸问题
履历资讯
中表明擅长多种资料库(Database)
履历资讯
中还表明有优化资料库的经验。
在决定要使用什麽资料库前,我会先分析专案的应用场景
:
商城
会有金流,所以资料稳定性与 Transaction 机制是很重要的。地图平台
,就会选择对 GIS 支援度高的资料库。在设计资料库时会画 ER Model
来分析资料间的关联与属性;在优化方面,为了要提高搜寻效率会在 Table 建立 Index
,同时也会依据实际业务设计栏位适合的长度及 Type
。
我们知道在 Table 建立 Index 可以增加搜寻效率,但你知道自己建立的 Index 有没有派上用场吗?笔者将在这个小节透过实作,带大家了解 Coverage Index (覆盖索引)
的意义。
SETP 1:建立测试用的 tmp_user Table
create table tmp_user (
id bigint(20) not null auto_increment ,
name varchar(255) not null,
password varchar(255) ,
index index_name (name),
primary key (id))
engine=innodb
default character set=utf8 collate=utf8_general_ci;
insert into tmp_user (name, password) values ("宝宝不说","123");
SETP 2:下 SQL 指令了解是否使用 Index
观察最後「Extra」栏位的资讯有否有
Using index
explain select id from user_table where name= '宝宝不说';
name
有建立 index,所以在查询到 name
後可以直接与 id
对应返回结果;因为 name 已经覆盖了查询资料的需求,所以称为 「Coverage Index」。explain select password from user_table where name= '宝宝不说';
name
找到「宝宝不说」对应的 id
,但接着要透过 id 这个 primary key
,在 Table 重新轮询才能取得这一列的完整资料。SETP 3:建立 Coverage Index 优化 SQL B
先将资料库 drop 掉:drop table tmp_user;
重新建立测试资料以及「Coverage Index」
为了避免用 primary key 再次从 Table 查询的耗能,我们可以把 select 与 where 用到的栏位(name、password)做联合索引
,这样就能够直接使用索引查询,而不需用 primary key 重新比对,这就是「Coverage Index」的应用。
create table tmp_user (
id bigint(20) not null auto_increment ,
name varchar(255) not null,
password varchar(255) ,
primary key (id))
engine=innodb
default character set=utf8 collate=utf8_general_ci;
insert into tmp_user (name, password) values ("宝宝不说","123");
alter table tmp_user add index name_password(name,password);
再次执行 SQL B:explain select password from tmp_user where name = '宝宝不说';
本次的查询就可以在「Extra」栏位看到 Using index
噜~
使用 ER Model 做规画
在需求规格出来後,我们可以先透过 ER Model 整理资料间的关联性,然後以此为基础设计资料库;向新人说明 Table 间的关联时,它也是一个非常棒的辅助工具。
设计合适的文字栏位
避免使用 TEXT/BLOB
这类的 Type,它们在查询时会消耗更多的效能。减少 SQL 写入次数
以 Insert 来做举例,假设有 1000 笔资料要写入 Table;一次插入 1000 笔的执行时间会远远小於分 1000 次插入的时间。
适当的增加冗余栏位
在设计资料库时要尽量符合三大正规化;但 Table 间的关联越复杂也会导致查询效率的下降
,因此有时会适当的增加冗余栏位,用牺牲磁碟空间的方式换取更高的查询效率。
定期审视资料库的规划
如果没有专门的 DBA,那资料库通常会有以下问题需要修正:
栏位长度开到最大
。新增许多无用栏位
。没有整理
不符合实际业务需求的检视表(View)
。许多 Index 并没有发挥作用
。MySQL
是世界上最流行的资料库之一,世界上有非常多的 Web Application 都采用它作为解决方案;但在被收购後分出了非常多的版本,有免费也有收费的
;而 PostgreSQL
基於 BSD/MIT 的 linecense,为完全开源的资料库
。
PostgreSQL 的优势
整合关联式资料与非关联式资料
。支持「二维、三维、曲线」的空间类型
,并有丰富的空间操作函数。联合资料库
。MySQL 的优势
在招募工程师时更容易
,遇到问题时也有丰富的社群资源提供解答。PostgreSQL 可以搭配 Connection Pool 的外挂解决这个问题,但架构上就会变更复杂。
应用场景
其实在 DB 的选择上,除了考虑专案适用的场景外,还要考量到
团队内的工程师对哪个比较擅长;思考万一发生意外时有谁可以救场
,不然灾难复原是一场恶梦。
考点:了解 Index 对资料库效能的影响
Index 的数量太多,会影向 DML(Insert、Update、Delete)的效能,因为 Table 资料更新时也要连带更新 Index
。
考点:确认求职者的 SQL 基本功
回传固定笔数
(ex:limit)。只抓取需要的栏位
。Index
来做搜寻。避免使用不兼容的型态
做比较,像是 FLOAT 跟 INT、CHAR 跟 VARCHAR。考点:确认求职者对 NoSQL 的认知
即便你的履历中没有写自己会 NoSQL,还是会遇到这类考题,所以建议至少有基础的认知。
MongoDB
这类的 NoSQL,就可以很灵活的对栏位进行调整。Redis
这类记忆体资料库,单一节点就能应付每秒 10 万次的读写请求。水平扩充
能力,只要增加新的服务器节点就能扩充资料库容量;且对於服务器的性能要求较低,可使用较便宜
的电脑进行扩充。考点:确认求职者是否有评估的能力与经验
我会考虑的点有资料量多寡、并发量、实时性、资料一致性、未来扩充性、资料稳定性、维护成本
。
以企业内部管理系统来说,因为资料量少、并发数少、未来扩充需求较低,所以会选择关连式资料库;如果是游戏的排行榜页面,因为资料量大、并发数高、且要求高的更新频率,所以我会考虑使用记忆体资料库(ex:Redis)。
感谢大家的阅读,如果喜欢我的文章可以订阅
接收通知;如果有帮助到你,按Like
可以让我更有写文的动力,我们明天见~
我在 Medium 平台 也分享了许多技术文章
❝ 主题涵盖「MIS & DEVOPS、资料库、前端、後端、MICROSFT 365、GOOGLE 云端应用、自我修炼」希望可以帮助遇到相同问题、想自我成长的人。❞
#以下内容皆由初学者撰写,有错误可能,不建议尽信 30天Python自学: Day01 Python...
本文将完成: 语义检索 从 IMDB影评档(100则)--> 从文字栏位'IMDB_plot'...
07 - Update gems & js 专案如果要长久,套件升级是一定是不可或缺的事,从...
上一回介绍 CC: Tweaked Advanced Computer 各个面向与特色後 今天来玩更...
现况 清洗後的图档,部分仍有红框等杂讯,或是中文字体颜色不同(蓝色、黑色),如下图。 若将含有不同颜...