哈啰,我们又见面了,前面经历了三天 DevOps
的训练,今天回归后端重要的一个环节,也就是资料库操作,今天来了解一下 MySQL 这个老派却还很常见的关联式资料库(Relational Database
)吧,构构。
MySQL
和 Django 预设使用的 SQLite
差在哪里 ?
可以参考 (2019) SQLite 与 MySQL 的差别 | Medium,我觉得这篇解释得不错 ~
简单来说,两者之间的差异可以比喻成 MySQL
是 大卡车、SQLite
是 机车,大卡车可以同时载很多货物,可是开着大卡车很不方便,要临时停下来上个厕所、买东西都很麻烦,也不是人人都会开大卡车;虽然也不是人人都会骑机车,但相对多数,机车的载货量小,可是很方便,想做什么就路边停着,虽然这样违法 XD,我知道你 get 到我想讲的点了,哈哈。
同理,MySQL
处理资料的吞吐量大,可 同时 处理多请求时的资料 (可以想成多人同时在浏览你的网页),可透过 TCP/IP 要资料,缺点是需要开着 Server,适合用在大型专案上;SQLite
则是处理资料的吞吐量小、不能同时 处理多请求的资料,但好处是轻量(档案小、安装快),不用开 Server (Serverless),适合用在行动装置上,Android
就是用 SQLite
。
我们之后讲 MongoDB
时,再来比较 关联式(Relational
) 和 非关联式(NoSQL
) 的差别吧,现在先来感受一下关联式的用法。
安装 MySQL
在 Windows
的安装过程可以参考 (2016) Windows 上的 MySQL 安装教学 (使用 MySQL Installer),安装过程中有一个简单的原则,如果你不知道那是什么,就都安装就对了,如果不知道是什么,就选预设的。
我在安装时,选择的是 Developer Default
的方案,再来就是它建议要安装的都安装。安装得选择太多,作为一个资料库新手,也无从讲起每个选择代表的意思,有兴趣可以等入门了之后,再去慢慢了解。安装的过程中,会觉得它非常啰嗦,但请耐住性子,稍微看过去每个步骤在做什么,然后用预设的选项即可,唯一要注意的是 root 使用者的帐号密码,不要设完就自己忘记了,作为学习用的,可以先设个简单的帐号密码,以免忘记。
安装完 MySQL 之后呢 ?
然后,我就面临到一个问题,我不知道我还能做些什么,因为我对 SQL 语法不熟,MySQL Workbench
的介面也很难上手,也无法确认 Django
要怎么做,才算是真的有连动到 MySQL
,直到我找到了这一篇 (2018) Django+MySQL 实例入门 | 掘金,超实用的文章,我整篇几乎都是照着它做出来的,它的 django 语法是 1.x 版的 (本篇是 Django 3.0.3 版),大部分程式码差不多,来一起跟着做吧。
安装后会出现两个视窗
一个是 MySQL Workbench
、一个是 MySQL Shell
,这两个的作用很明显,一个是图形化介面、一个是指令介面,没错,浅显易懂,可是我觉得图形化介面并没有我想像中的好用,所以我在这边选择用 shell 的方式来了解 MySQL
。
先开启 MySQL Shell
开启 MySQL Shell
之后,预设会在 js mode
,也就是可以用 javascript 来取用 MySQL
,我猜应该是我安装的时候有装到 js connector,不过今天我们不用这个,我们用纯 SQL 指令。
切到 SQL mode
mysql> \sql
连接到 MySQL
server,填入密码
mysql> \connect root@127.0.0.1:3306
Creating a session to 'root@127.0.0.1:3306'Please provide the password for 'root@127.0.0.1:3306': *****Save password for 'root@127.0.0.1:3306'? [Y]es/[N]o/Ne[v]er (default No):Fetching schema names for autocompletion... Press ^C to stop.Your MySQL connection id is 120Server version: 8.0.19 MySQL Community Server - GPLNo default schema selected; type \use <schema> to set one.
查询目前所有的 database 有哪些
mysql> show databases;
等同于 mysql> show schemas;
别忘了在输入 SQL 语法时,要有 ;
分号作为一个指令的结束
建立一个叫作 django_mysql
的 database
mysql> create database django_mysql;
(注意 django_mysql
这个 database 的名字,就是等等要用在 django settings.py
设定 DB 的名字)
进入到 database 里
mysql> use django_mysql;
离开 database
恩...,目前还没有找到指令,可以先关掉整个 shell,再重新开一次 shell
将之前在 django shop 里面写的 Product
model 转成 MySQL table
settings.py
...DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql','''注意 `django_mysql` 这个名字,要跟你在 MySQL shell 里创建的 database 名字,一模一样不然等一下 makemigrations 会出错''' 'NAME': 'django_mysql', 'USER': 'root', 'PASSWORD': 'admin', 'HOST': '127.0.0.1', 'POST': 3306, }}...
先把旧的 sqlite migrations 删掉,然后对 shop
这个 app 来 makemigrations
$ python manage.py makemigrations shop
结果:
Migrations for 'shop': shop\migrations\0001_initial.py - Create model Product
$ python manage.py migrate
Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions, shopRunning migrations: Applying shop.0001_initial... OK
再回 MySQL shell 检查是不是有新增 table 成功
mysql> show tables;
+----------------------------+| Tables_in_django_mysql |+----------------------------+| auth_group || auth_group_permissions || auth_permission || auth_user || auth_user_groups || auth_user_user_permissions || django_admin_log || django_content_type || django_migrations || django_session || product <-- |+----------------------------+11 rows in set (0.0010 sec)
除了 product
之外的 table,都是 django 预设的。如果你看的到这边的 tables,就代表 你已经成功将 django 和 MySQL 连动了 ! 恭喜夫人贺喜老爷 ~
接下来就是后端资料库的「增、查、改、删」的基础步骤练习。
检查 table 内的栏位们是否正确 (desc
,describe)
mysql> desc product;
+----------------+---------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+----------------+---------------+------+-----+---------+----------------+| id | int | NO | PRI | NULL | auto_increment || name | varchar(100) | NO | | NULL | || price | decimal(65,0) | NO | | NULL | || img | varchar(100) | NO | | NULL | || on_sale | tinyint(1) | YES | | NULL | || tag | varchar(20) | YES | | NULL | || percent_off | decimal(30,1) | YES | | NULL | || sale_price | decimal(30,0) | YES | | NULL | || bought_counter | decimal(30,0) | NO | | NULL | || created_date | datetime(6) | NO | | NULL | || published_date | datetime(6) | YES | | NULL | |+----------------+---------------+------+-----+---------+----------------+11 rows in set (0.0016 sec)
(增) 透过 django 加点资料进到 product
的 table
views.py
from django.http import HttpResponsefrom .models import Productimport randomdef insert_view(request): for i in range(5): product = Product() product.name = "测试" + str(random.randint(0, 5)) product.price = random.randint(1, 500) product.save() return HttpResponse("批次新增资料完成")
urls.py
...urlpatterns = [...,path('insert/', insert_view),]
把 django 跑起来 !$ python manage.py runserver
再到浏览器访问 127.0.0.1:8000/insert/
确认资料是不是真的有塞进去 product 的 table 里
sql> select * from product;
我这边不小心执行了三次 XD
(查) 透过 django 查询 table 里的资料
views.py
新增一个 lookup_view
的页面
def lookup_view(request): result = Product.objects.all() mlist = [] for item in result: content = {"product name": item.name, "price": float(item.price)} mlist.append(content) return HttpResponse(mlist)
urls.py
...urlpatterns = [...,path('insert/', insert_view),path('lookup/', lookup_view),]
结果:
(改) 透过 django 修改 table 中的资料
views.py
def modify_view(request): product = Product.objects.get(id=1) product.name = "我是后来才修改的产品" product.save() return HttpResponse('修改完成,请到 SQL shell 下指令\nsql> select * from product where id=1')
urls.py
...urlpatterns = [...,path('insert/', insert_view),path('lookup/', lookup_view),path('modify/', modify_view),]
结果:
只查询其中一项 id=1 的资料
sql> select * from product where id=1;
查询全部
sql> select * from product;
(删) 透过 django 删除 table 中的资料
views.py
def delect_view(request): product = Product.objects.get(id=1) product.delete() return HttpResponse('删除 id=1 的资料成功,请到 SQL shell 下指令\nsql> select * from product')
urls.py
...urlpatterns = [...,path('insert/', insert_view),path('lookup/', lookup_view),path('modify/', modify_view),path('delete/', delete_view)]
结果:
检查
sql> select * from product;
id=1 的那一项已经被我们删掉了
如果是要删除不存在的资料呢 ?
也就是再执行一次我们的 delete 页面,因为里面已经没有 id=1 的资料了,所以会报 DoesNotExist
的 Error message
单日心得总结
今天刚入门 MySQL
的时候,真的有点不知所措,MySQL Workbench
这个图形化介面的工具,实在对新手很不友善,我一直想找我的预设 database 到底有哪些,我都已经用指令找出来了,可是在 workbench 就是看不到,结果到很久很久后,我才发现有个很小颗的 Schemas
的按钮。
按下 Schemas
的按钮,我才发现原来藏在这 ! 该死,浪费我时间 QQ
但工具这种东西就是这样,当你不会用的时候,都会觉得它是烂东西,可是当你掌握它的操作逻辑时,就换成是你驾驭它了,随时可以用它来达到你想要的功能,真的要用过才会觉得没什么。
我是 RS,这是我的 不做怎么知道系列 文章,我们 明天见。
喜欢我的文章吗? 赶快来看看我都发了什么文章吧:我的文章目录欢迎阅读我的上一篇: [不做怎么知道系列之Android开发者的30天后端养成故事 Day13] - 老闆,来碗自动化测试吧 #让科技帮你省时间 #持续整合 #CircleCI欢迎阅读我的下一篇: [不做怎么知道系列之Android开发者的30天后端养成故事 Day15] - 后端核心中的新星 #资料库 #MongoDB #NoSQL
今天做了一个新的尝试 !