这是我参与[第五届青训营]伴学笔记创作活动的第3天
课程笔记
- 中间层:坚固持久化和内存友好的存储器Persistent Memory
- [缓存]重要,贯穿整个存储体系
- [拷贝]昂贵,尽量减少
RAID技术
- 单机存储系统做到:高性能/高性价比/高可靠性
- RAID 0 + 1:【取两个极端再加和】
- 结合RAID 0和1
- 真实空间利用率仅50%
- 容错率强,写入带宽好
关系型&非关系数据库
- 关系型:结构化友好,支持事务,支持复杂的查询语言
- 关系代数:对关系作运算的抽象查询语言【交、并、笛卡尔积……】
- SQL = 一种DSL = 方便阅读的关系代数
- 事务:A[原子性] C[一致性] I[隔离性] D[持久性]
- 非关系型:[半]结构化友好,[可能]支持事务,[可能]支持复杂的查询语言
存储
- 单机存储:本地文件系统&key-value存储【RocksDB】
- Index Node & Directory Entry
- put(k,v) & get(k)
- 分布式存储:分布式文件系统[HDFS] & 分布式对象存储[Ceph]
我的记录&MySQL基础
前言:
- show create database 数据库名; //查询已存在数据库的字符集
- show databases; //查询MYSQ有哪些数据库
- use 数据库名; //使用数据库
- show tables; //查询某数据库的表
- select * from 表名; //查询表内容
- desc 表名; //查询表结构
数据库的-增-删-改-查
——《增》——
create database if not exists 数据库名;
character set = utf-8;
——《删》——
drop database 数据库名;
——《改》——
alter database 表名
character set = utf-8;
——《查》——
show databases;
表结构-增-删-改-查
——《增》——
create table 表名 if not exists(
字段名1 数据类型 约束条件 auto_increment,【列级】
字段名2 数据类型,
primary key(字段1,字段2……))charset utf8;【表级】
①>实体完整性约束(主键、候选键、自增)
1.主键:primary key【非空、唯一】
alter table 字段名 drop primary key; //删除主键
2.复合主键:primary key(字段1,字段2……)
3.候选键:nuique【用于外键引用】
4.自增:auto_increment【数据类型只能是(int/float),字段只能是(主键/候选键)】
auto_increment = 12;{设置初始值,默认1}
②>参照完整性约束:(外键)
{先建父表再建子表}
外键:foreign key【表与表之间建立关联】
foreign key(字段名) references 表名(字段名)
③>用户定义完整性约束:(非空、默认值、CHECK)
非空:not null
默认值:default(default '女')
CHECK:check(score>=0 and acore<=100)
——《删》——
drop table 表名;
——《改》——
①>添加字段名:
alter table 表名 add 字段名 数据类型 after 字段名
②>修改字段名和数据类型:
alter table 表名 change 旧字段名 新字段名 新字段名数据类型
③>修改一个字段的数据类型:
alter table 表名 modify 字段名 数据类型
④>修改表的名字:
alter table 表名 rename 新的表名
⑤>表结构的复制:
create table 新表名 like 旧表名【只拷贝表结构,不拷贝表内容】
——《查》——
select * from 表名; //查询表内容
desc 表名; //查询表结构
表内容-增-删-改-查
——《增》——
①>不完全插入:
insert into 表名 (字段名1,字段名2…) values(值1,值2……);
②>完全插入:
insert into 表名 values(值1,值2…,值n);
③>插入数据(纯在一样的内容,不一样的就修改)
replace into 表名 values(值1,值2……)
——《删》——
drop table 表名;
delect from 表名 where 条件
——《改》——
update 表名 set 列名1=值,列名2=值 where 条件;
——《查》——
①>查询所有字段:
select * from 表名;
②>查询指定字段:
select 字段1、字段2 from 表名;【可增加简单表达式】
》聚合函数:
①>count() [统计个数]
count(字段名) //不统计空值
count(*) //统计空值
②>sum() [求和]
sum(字段名)
③>avg[求平均数]
avg(字段名)
④>max() min() [最大值,最小值]
》分组查询:
①>group by
//通过name的值进行聚合
select name,sum(number) from test group by name;
②>having [筛选]
//统计test表中学号平均年龄小于19岁的id
select id,avg(age)
from test
group by id
having avg(age)<19;
》多表查询:
①>全连接查询:
select * from 表名1,表名2……;
②>内连接查询:
select * from 表名1 join 表名2 on 条件;
③>外连接查询:
左外连接(left outer join)
select * from 表名1 left outer join 表名2 on 条件;
右外连接(right outer join)
select * from 表名1 right outer join 表名2 on 条件;
--- --- ---
》条件查询:
①>where[条件查询]
select 字段1、字段2…… from 表名 where 表达式{=,or,and}
②>in
where 字段 in('字段1','字段2')
③>like[模糊查询]
where 字段 like 'm%'; //以开头的字段名
where 字段 like '_o__'; //以_o__形式的字段
④>is null 【判断字段是否为空】
where 字段 is null
⑤>as[字段别名]
select 原始字段 as '显示字段' from 表名
⑥>distinct[去掉重复行]
select distinct 字段名 from 表名 //查询去掉重复信息
⑦>order by [排序]
order by id desc; //降序排序
order by id asc; //升序排序
⑧>limit[控制显示数据条数]
select * from test limit 1,4 //显示[1,4)行的数据
Code
package utils
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
// 定义全局变量
var (
Db *sql.DB
err error
)
func init() {
Db, err = sql.Open("mysql", "root:123123@tcp(localhost:3306)/test")
if err != nil {
panic(err.Error())
}
}
package model
import (
"fmt"
"gitee.com/mall_lucy/my_go_studycode/PrincipleLanguage/GORM/utils"
)
type User struct {
ID int
Username string
Password string
Email string
}
// AddUser 添加User方法
func (user *User) AddUser() error {
// 写sql语句
sqlStr := "insert into users(username,password,email) values(?,?,?)"
/*
// 执行(不执行预编译)
_, err := utils.Db.Exec(sqlStr, "admin2", "888888", "admin@qq.com")
if err != nil {
fmt.Println("执行出现异常", err)
return err
}
*/
// 预编译
inStmt, err := utils.Db.Prepare(sqlStr)
if err != nil {
fmt.Println("预编译异常", err)
return err
}
// 执行
_, err2 := inStmt.Exec("admin", "123456", "123@qq.com")
if err != nil {
fmt.Println("执行异常", err)
return err2
}
return nil
}
// 根据用户的id从数据库中查询一条记录
func (user *User) GetUserByID() (*User, error) {
// 写sql语句
sqlStr := "select id,username,password,email from users where id = ?"
// 执行一次查询返回一条结果
row := utils.Db.QueryRow(sqlStr, user.ID)
// 声明
var id int
var username string
var password string
var email string
err := row.Scan(&id, &username, &password, &email)
if err != nil {
return nil, err
}
u := &User{
ID: id,
Username: username,
Password: password,
Email: email,
}
return u, nil
}
// 获取数据库中所有记录
func (user *User) GetUsers() ([]*User, error) {
// 写Sql语句
sqlStr := "select id,username,password,email from users"
// 执行
rows, err := utils.Db.Query(sqlStr)
if err != nil {
return nil, err
}
// 创建User切片
var users []*User
for rows.Next() {
// 声明
var id int
var username string
var password string
var email string
err := rows.Scan(&id, &username, &password, &email)
if err != nil {
return nil, err
}
u := &User{
ID: id,
Username: username,
Password: password,
Email: email,
}
users = append(users, u)
}
return users, nil
}
package model
import (
"fmt"
"testing"
)
func TestMain(m *testing.M) {
fmt.Println("测试开始:")
m.Run()
}
func TestUser(t *testing.T) {
fmt.Println("开始测试User中的相关方法")
//执行子测试函数
t.Run("测试添加用户:", testGetUser)
}
// 如果函数名不是以Test开头,那么该函数默认不执行,我们可以将它设置成一个子测试函数
func TestAddUser(t *testing.T) {
fmt.Println("测试添加用户:")
user := &User{}
// 调用添加用户方法
user.AddUser()
}
// 测试获取一个User
func TestGetUserByID(t *testing.T) {
fmt.Println("查询一条记录的子测试函数执行:")
user := User{
ID: 1,
}
// 调用获取User的方法
u, _ := user.GetUserByID()
fmt.Println("得到的User的信息是:", u)
}
// 测试获取所有user
func testGetUser(t *testing.T) {
fmt.Println("测试所有记录:")
user := User{}
// 调用获取说有User的方法
us, _ := user.GetUsers()
// 遍历切片
for k, v := range us {
fmt.Printf("第%v用户是%v:\n", k+1, v)
}
}