Lua Web快速开发指南(6) - Cache、DB介绍

"数据库"与"缓存"的基本概念

数据库与缓存是服务端开发人员的必学知识点.redis

数据库

"数据库"是一种信息记录、存取的虚拟标记地点的集合统称. 好比现实生活中, 咱们常常会用到文件柜、书桌等等数据存取容器.数据库

在对容器进行数据存取的时候, 咱们会为每一层打上一个标签表示一种分类项. 而这种在数据库中划分子分类造成了的概念. 这就是咱们一般所说的结构化数据库.数组

因为一般数据表之间可能会存在依赖关系, 某一(或者多)层一般可能会用于同一种用途. 这种用途将一层划分为索引表, 二层划分为分类表, 三层划分为数据表.缓存

实现这种功能与依赖关系的数据库, 咱们称之为: 关系型数据库. 它能够定义一套规范而且创建数据存取模型, 这样方便维护一整套结构化的数据信息.安全

每当咱们须要对数据进行结构化操做(查询、增长、删除、修改)的时候, 须要在计算机中用一种通俗易懂的语言表达方式来进行助记. 这种结构化查询语言称之为SQL.bash

缓存

咱们一般将数据存储完毕后, 能经过指定或特定的一(多)种方式对数据进行操做. 在项目开发的初期, 这并无太大的问题.数据结构

可是随着数据量的不断增大, 在数据库的内存中已经放不下这么多数据. 咱们的数据逐渐没法被加载到内存中: 只会在使用的时候才会进行(随机)读取. 而这会加大磁盘I/O.框架

咱们知道一般磁盘的读写速度基本上会比内存读写慢几个数量级(即便是SSD), 大量请求可能瞬间将磁盘IO占满并出现数据库的CPU利用率低、内存频繁进行修改/置换等问题.分布式

为了解决这些问题, 出现了不少解决方案: 读、写分离、分表分库等等. 虽然有了这些方案, 可是也一样回引来新的问题: 主从同步、分布式事务等问题.工具

"缓存"则是近十年兴起的概念, 它的本质是一份数据结构化存储在内存中的副本. 高级的缓存咱们也能够将其称之为内存数据库NOSQL(非关系型)数据库.

"缓存"也是一种"另类"解决数据库问题点一种手段! 它经过丰富的数据结构扩展了数据模型的组合能力, 经过简单的使用方法与高效的链接方式提供更好数据操做方式.

"缓存"将查询、更新较为频繁的数据组成一个集合加载进内存中, 较少使用的数据序列化到磁盘内部. 高效利用内存的同时, 根据变化的状况合理更新、删除缓存.

这样的方式配合数据库都读、写分离与数据分区将数据合理的从一个数据集副本分散到多个数据集副本, 有效的减小性能问题点产生而且提高了整个业务系统的横向扩展能.

DB库

DB库是cf框架封装自MySQL 4.1协议实现的客户端链接库, 提供MySQL断线重连、SQL重试、链接池等高级特性.

Cache

Cache库是cf封装自Redis 2.0协议实现的客户端链接库, 提供Redis断线重连、命令重试、链接池等高级特性.

API学习

1. DB API

在使用下面的API以前, 请先确保已经导入库: local DB = require "DB".

1.1 DB:new(opts)

opts表的参数决定如何链接到MySQL, 表属性以下:

host - MySQL主机名或IP地址(string类型).

port - MySQL端口号(int类型).

charset - MySQL字符集设置.

database - MySQL库的名称.

username - MySQL用户帐户(string类型).

password - MySQL用户密码(string类型).

max - MySQL的最大链接池大小(int类型).

这个方法返回一个新建立db对象

1.2 DB:connect()

开始链接MySQL. 链接成功返回True, 不然将会持续进行链接而且输出链接失败缘由的日志.

1.3 DB:query(SQL)

数据库查询语句调用方法, SQL为string类型的的一个标准SQL语句.

返回值为ret与err. 查询成功ret为一个结果集数组, 在发生错误时未nil, err为错误信息.

2. Cache API

在使用下面的API以前, 请先确保已经导入库: local Cache = require "Cache".

2.1 Cache:new(opts)

opts表的参数决定如何链接到MySQL, 表属性以下:

host - Redis主机名或IP地址(string类型).

port - Redis主机端口号(int类型).

auth - Redis主机设置的密码, 默认为:nil.

db - Redis的数据库设置.

max = 最大链接池大小(int类型).

此方法返回一个新建立的Cache对象.

2.2 Cache:connect()

开始链接Redis. 链接成功返回True, 不然将会持续进行链接而且输出链接失败缘由的日志.

2.3 Cache:API(...)

Cache支持大部分的redis API, 目前测试过多API在script/test_Cache.lua文件内部都有展现.

DB库的操做流程

DB库的操做与使用流程很是简单, 其目标是简化开发人员在业务编写过程当中的使用难点.

建立数据库与数据表

启动一个MySQL实例而且初始化完毕, 具体安装与初始化方法根据平台不一样而不一样, 这再也不本文讲解范围内.

而后咱们使用默认的root用户而且root帐户、密码设置完毕. 这里为了演示方便, 咱们将root密码设置为: 123456789.

建立一个叫cf_mall的数据库字符集编码都设为utf-8. 而且在cf_mall数据库中建立一个叫作cf_users的表, 以下所示:

# 建立`cf_mall`数据库
CREATE DATABASE IF NOT EXISTS `cf_mall` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

# 建立`cf_users`用户表
CREATE TABLE IF NOT EXISTS `cf_mall`.`cf_users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`age` tinyint(3) unsigned NOT NULL COMMENT '用户年龄',
`name` varchar(255) NOT NULL COMMENT '用户名',
`username` varchar(255) NOT NULL COMMENT '用户帐户',
`password` varchar(255) NOT NULL COMMENT '用户密码',
`email` varchar(255) NOT NULL DEFAULT '' COMMENT '用户邮箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

以上数据库建立语句能够在一些MySQL GUI工具中直接运行.

测试DB库的API写入数据

如今, 让咱们利用上面学到的API尝试将做者的信息写入进去. 同时为了不密码原文显示, 咱们须要使用crypt库的base64方法将密码进行编码.

local crypt = require "crypt"
local DB = require "DB"
local db = DB:new {
	host = "localhost",
	port = 3306,
	username = 'root',
	password = 123456789,
	database = "cf_mall",
	charset = "utf8"
}

db:connect()

db:query(string.format([[
	INSERT INTO `cf_mall`.`cf_users`
		(`name`, `age`, `username`, `password`, `email`)
	VALUE
		('%s', '%s', '%s', '%s', '%s')
	]],
	'水果糖的小铺子', '29', 'candymi', crypt.base64encode('123456789'), '869646063@qq.com')
)
local ret, err = db:query("SELECT * FROM `cf_mall`.`cf_users` WHERE `name` = '水果糖的小铺子'")
if not ret then
	return print(ret, err)
end
return print('name:', ret[1].name, 'password:', ret[1].password, 'email:', ret[1].email)

检查问题

最后咱们检查数据库内是否已经写入了咱们须要存储的数据. 若是使用的SQL有语法错误致使写入失败, 请使用print检查db:query操做否出现错误.

同时咱们在console控制台上能够检查是否输出了咱们刚才写入到cf_users的信息.

Cache库的操做流程

Cache库拥有很是简单的使用方法, 几乎能运行全部Redis已提供的命令. 而且协议是二进制安全的(binary safe).

启动一个Redis实例

启动并运行一个redis实例. 具体安装与运行方法根据平台不一样而不一样, 这再也不本文讲解范围内.

而且这里为了演示示例简单, 咱们将不设置任何auth而且使用默认的db.

将数据加载到Redis

咱们将列出目前已知的一些知名大众化语言, 而后将其写入到Redis中.

local Cache = require "Cache"

local cache = Cache:new {
	host = 'localhost',
	port = 6379,
}

cache:connect()
local ok, msg = cache:rpush("languages", "C", "C++", "Java", "Golang", "Ruby", "Python", "PHP", "Lua")
if not ok then
  return print(ok, msg)
end
print("当前language的总数为:", msg)

问题排查

最后, 让咱们用Redis自带的命令行工具查看是否真实写入了数据.

[candy@MacBookPro:~] $ redis-cli
127.0.0.1:6379> lrange languages 0 -1
1) "C"
2) "C++"
3) "Java"
4) "Golang"
5) "Ruby"
6) "Python"
7) "PHP"
8) "Lua"
127.0.0.1:6379>

能够看到数据已经写入进去. 若是发送参数错误与语法发生错误, msg将会是您排查错误的有效信息.

更多

更多API详情请参考MySQL、Redis的使用文档而且在实际开发中进行体验.

继续学习

下一章节咱们将继续学习如何利用httpc库请求第三方接口

相关文章
相关标签/搜索