0%

写一个资源共享服务 02.数据存取初步

写一个资源共享服务 2.数据存取初步

任何一个项目都是从小慢慢增长的, 但是这里面出现了一个非常棘手的难题, 如何避免“屎山”代码? 如何在更改业务逻辑或者添加新功能的时候最大限度的方便自己?

我们修改代码的某些部分, 新增功能的时候好家伙需要修改很多现有代码, 最后把自己绕进去这样是不行的。

因为我们的项目最开始的时候是一个简单的单用户资源共享服务, 但是后期我们完全可以在它的基础上添加更多功能, 最后这个项目很有可能变成一个类似于网盘的东西, 所以开始起步的时候考虑后续项目的可持续开发。

这次更新应该很慢, 而且所有的东西讲的都比较细致, 应该说前方高能; 请坐稳扶好, 当然也逃脱不了特别琐碎, 所以很多时候你完全可以跳过去!

数据存取模块概述

我们可以在一个叫storage的模块下统一管理数据存取业务逻辑,

对外提供一个叫getStorage的函数, 该函数返回一个Storage对象, 客户程序员可以用这个对象来存取数据。

Storage对象必须实现若干方法, 方便客户程序员使用数据存取模块。

开发中的角色转换

我们编写不同模块的时候角色都不太一样, 比如编写数据存取模块的时候我们只考虑当前模块内部的业务逻辑和对外暴露的接口方法, 至于谁在什么时候在什么场景下调用你外部接口不应该关心。

等到开发web后台服务的时候也是同样的道理, 合理调用数据存取模块的接口方法完成当下业务逻辑就可以了, 至于数据存取内部是如何的, 不应该分心去关注。

总之你把自己想象成好几个角色就可以了, 有时候你是数据存取模块的开发者, 有时候你是web后台开发者, 有时候你是Windows桌面开发者, 有时候你是web前端开发者。

人类的头脑虽然非常强大, 但是毕竟是肉长的有很大的局限性, 为了减轻大脑的工作压力需要合理的聚焦局部工作, 如果我们同时编写web后台前端和独立客户端很容易出现无所适从, 不知道该从哪里下嘴。

咱虽然有双手但是不能给两三个人同时推拿, 同样的道理编写程序也一个一个来。

关于角色转换到此为止, 一句话总结就是, 泾渭分明; 各司其职!

毫无负担的修改任何模块而不必担心无形当中破坏其他模块。

数据存取内部

内部最关键的是选择合适的数据存储方案了, 简单列举一下这些方案:

  • 文件系统

  • 关系型数据库

  • 非关系型数据库

    这里我选择关系型数据库sqlite3, 可以从实际触发选择其他方案, 但是必须对外提供统一接口, 比如我现在看着项目比较简单没有太大额外需求所以选用sqlite3,

    但是后续sqlite3不够用了, 想要替换成mongoDB或者mysql, 这个时候你要保障依赖这个模块的其他模块不受影响, 当然这一点我们不厌其烦的重复了好几遍了。

数据存取模块的设计

如果这是一个Java或者C#项目那么很自然的定义一个接口, 所有数据存取方案必须实现这个接口, 而对外暴露这个接口就可以了。

但是python属于动态类型语言没有接口这样的概念, 所以我们需要其他方式来达到和接口相同的效果。

在我们的项目文件夹下创建一个叫service的文件夹, 这里存放我们服务端所有模块, 包括web后台web前端和我们今天的主角数据存取模块。

在service文件夹下创建apps文件夹,

然后在apps文件夹下继续创建文件夹, 名称为storage存放我们的数据存取模块的代码。

到此为止我们的数据存取模块可以着手编码了, 不过先需要简单介绍一下我们的SQL。

SQL介绍

SQL是结构化查询语言(Structured Query Language)的简写, 是RDMS(关系型数据库管理系统)锁遵循的标准。

那么SQL; RDMS; mysql; sqlite这些有什么区别和联系呢?

首先sql是用于数据库查询的标准语言, 而RDMS是某种类型的软件, 比如mysql; sqlite都属于RDMS软件。

而这些RDMS软件遵循SQL标准。

所以我们可以得出一个结论, 只要是RDMS软件都可以使用sql语言来对数据库做增删改查。

无论是sqlite还是mysql最核心的sql查询语句是一样的, 当然数据库领域在统一标准方面远远比不上web!

所以出现了这些RDMS软件各自为政的情况, 对我们学习和使用sql带来了巨大的不必要的麻烦。

你管不了用户使用何种web浏览器, 但是你完全可以决定自家服务用何种RDMS软件, 所以浏览器的统一标准是必然的; 也是迫切需要解决的问题, 而RDMS统一标准这一块不那么迫切。

所以各个RDMS厂商在sql核心的基础上开发出了很多独具特色而互不兼容的扩展功能, 更有甚者某些特性也许不兼容标准sql。

扯了那么多, 总之一句话你掌握sql是不够的, 还需要参考某个具体的RDMS软件的手册,

数据库介绍

从上面的论述可知, SQL是操作数据库的标准语言, 而RDMS是具体的数据库管理软件, 那么数据库本身是如何表现的呢?

数据库本质就是计算机上的若干普通文件而已, 和你的mp3音乐; txt小说没有本质区别。

比如sqlite的数据库就是一个后缀名为.db的普通文件, 值得注意的是一个sqlite的数据库没有办法用MySQL来操作, 。

反过来你也没办法用sqlite来操作MySQL的数据库。

这里也回答了为什么交换数据用xml; json, 而不是直接交换数据库。

因为xml和json是一个统一的格式可以在任何软件系统之间无障碍流动, 和我们常见的mp3音乐一样, 但是数据库是软件专用格式, 就像受版权保护的音乐文件一样, 你即便拿到了文件也播放不了。

数据表

数据库是有若干个相互有关联或者无关联的数据表组成的, 值得注意的是一个数据库必须至少有一个数据表。

所谓的数据表和我们生活里常见的表格十分相似, 估计数据库的设计灵感就是来源于表格。

我们知道表格的格式事先严格规定的, 比如姓名; 年龄; 籍贯性别, 不允许乱写, 姓名填到年龄一栏; 年龄写在姓名一栏肯定是不行的, 而数据表也一样的道理。

而且比我们生活中的表格更加严格, 比如这里假定有一个论坛用户管理数据表。

  • 用户ID 整数类型 自动分配

  • 昵称 字符串类型 不能为空

  • 密码 字符串 不能为空

  • 邮箱地址 字符串 可以留空

  • 注册时间戳 长整数类型 不能为空

    这个用户数据表有若干字段, 用户id; 昵称; 密码; 邮箱和注册时间。

    这些字段的约束也不尽相同, 有的是整数类型; 有的是字符串类型, 有的自动分配有的可留空; 有的不可留空。

    我们在表里存取数据之前需要设计表的格式, 如同上面所示, 而后可以用sql语句来对这个数据库做增删改查了。

    一个用户的信息就是一条记录, 或者叫一行数据, 而一条记录有若干字段来组成, 比如用户信息有id; 昵称; 密码; 邮箱和注册时间这几个字段。

    一条记录和一行数据一个意思; 某个字段和某列数据也是一个意思。

SQL核心语句

下面是最核心的sql增删改查语句, 需要牢记在心, 用法也十分复杂需要随时查阅手册。

  • insert 增加数据 新用户注册

  • delete 删除数据 用户注销账号
    update 修改数据 用户更改信息

  • select 查询数据 查看用户信息

    上面的几个sql语句是整个关系型数据库的灵魂, 基本用法必须掌握, 高级用法可以随手查阅文档; 当然现在很多开发框架提供了非常方便的操作数据库的方法, 不用手写底层sql语句。

总结

最后做个简单总结。

SQL是用于关系型数据库查询的标准语言; RDMS是关系型数据库管理软件, 主要有mysql; sqlite; sql server等等, 这些RDMS不一定完全兼容sql标准, 而且各自为政发展出了很多各具特色的功能。

关系型数据库有若干数据表组成, 而数据表的格式是事先严格规定的, 可以使用insert; delete; update和select语句来对数据做增删改查。

非关系型数据库

关系型数据库很好用很强大, 但是不够灵活, 比如我准备给论坛的用户信息加上手机号, 那么必须要修改数据表; 带来很麻烦的一大堆问题, 带来连锁反应。

修改用户数据表可能要跟着修改主题数据表, 如果这是更大的系统呢? 比如电商系统, 那么要处理的事情就多了, 总而言之关系型数据库在某些场景下不是那么灵活, 这个时候出现了非关系型数据库。

非关系型数据库没有标准的查询语言, 对数据的格式没有任何要求, 比如mongoDB, 而redis上可以存取数据结构。

总之如果不习惯关系型数据库的繁琐笨拙, 那么可以选用非关系型数据库系统。

两者的关系不是非此即彼, 而是相辅相成, 我们根据自身需要选用合适的数据存取方案就可以了。

关于数据库我们说了很多, 接下来该实际动手实践一下了。

下次我们开始编写storage模块, 而这一模块就是使用了sqlite这个数据库管理软件, 更妙的是python内置了sqlite。

未完待续……