数据库的三范式

范式概念

在关系型数据库中,设计数据库时要考虑遵循一定的规则,这种规则就是范式。

实际上,数据库一共有六种范式,但一般设计数据库的时候,只需要遵守到3NF(第三范式)即可。
1NF 2NF 3NF BCNF 4NF 5NF

第一范式 1NF

第一范式主要强调原子性,即数据库的每一列都是一个不可再分割的基本数据项。

例:下表不满足第一范式

学号 姓名 家庭电话及住址
23333 马猴烧酒 166 xxxx xxxx,唐辛子星

修改后即可满足第一范式

学号 姓名 家庭电话 住址
23333 马猴烧酒 166 xxxx xxxx 唐辛子星

第二范式 2NF

第二范式主要强调唯一性,即数据表中每行都必须可以被唯一地区分,主要是为了防止数据重复,通常是使用一个主键来唯一标识一条记录。
满足第二范式就肯定满足第一范式。

  • 完全依赖、部分依赖
    因为主键可以由多列共同组成,
    当且仅当该行数据由主键中所有列共同确定时,我们说这条数据完全依赖于主键。
    当该行数据仅需要主键中的部分列即可确定时,我们说这条数据部分依赖于主键。

:完全依赖

学号(主键) 科目(主键) 分数
23333 数学 99

分数完全依赖于学号和科目,二者缺一不可。

:部分依赖

学号(主键) 姓名(主键) 科目(主键) 分数
23333 张三 数据库原理及应用 88

分数部分依赖于上述三个主键,原因:学号就可以确定出某位学生的姓名,分数依赖于科目和(学号姓名)在没有重名的情况下

第三范式 3NF

非主属性之间不能相互依赖,必须直接依赖候选关键字。
例:下表不满足第三范式

学号(主键) 姓名 班级 学生电话 班主任姓名 班主任电话
23333 张三 985211 168 xxxx xxxx 李四 189 xxxx xxxx
23334 王五 985211 199 xxxx xxxx 李四 189 xxxx xxxx

班主任的姓名、班主任的电话跟主键学号没有直接的关系,只有间接的关系(可以通过学生的班级了解到班主任的姓名电话)。故该表的非主属性班主任姓名、班主任电话依赖该表的非主属性班级,且间接依赖关键字学号。

修改后满足第三范式:

学号(主键) 姓名 班级 学生电话
23333 张三 985211 168 xxxx xxxx
23334 王五 985211 199 xxxx xxxx
班级 班主任姓名 班主任电话
985211 李四 189 xxxx xxxx
  • 直接依赖、传递依赖(函数依赖、间接依赖)
    a依赖b,b依赖c,则a肯定依赖c,这就是传递依赖。

学号 姓名 班级 班主任姓名
23333 张三 985211 李四

班主任姓名依赖于班级,班级依赖于学号,所以班主任姓名传递依赖学号,直接依赖班级。

Gin框架中使用数据库——Go Gin框架(七)

安装MySQL数据库

MySQL官方链接:https://dev.mysql.com/downloads/mysql/
Debian:sudo apt install mysql-5.7
安装过程:略

Go 安装MySQL驱动

go get "github.com/go-sql-driver/mysql"

在项目中使用MySQL

在go mod模式下,还需要在项目中引用mysql模块

go.mod文件

module MonaGinWeb

go 1.15

require (
    github.com/gin-gonic/gin v1.6.3
    github.com/go-sql-driver/mysql v1.5.0
)

在go中连接MySQL

import (
    "database/sql"
    "log"
    "strconv"
)

var db *sql.DB

func init() {
    c := MySQLConnInfo{
        user:       "",
        password:   "",
        connMethod: "tcp",
        host:       "",
        port:       0,
        dbname:     "",
        otherArgs:  "",
    }
    //数据库连接字符串
    //"user:password@tcp(host:port)/dbname"
    connStr := c.user + ":" + c.password +
        "@" + c.connMethod + "(" + c.host + ":" + strconv.Itoa(c.port) + ")/" +
        c.dbname + c.otherArgs
    if temp, err := sql.Open("mysql", connStr); err == nil {
        db = temp
    } else { //连接出现错误
        log.Fatal(err.Error())
        return
    }
}
  • func Open(driverName string, dataSourceName string) (*DB, error):该函数用于打开程序与SQL数据库的连接。其会返回创建(连接成功)的一个DB指针,有两个参数:
    • driverName string:用于指定数据库引擎
    • dataSourceName string:用于传入数据库的连接字符串

MySQL的增删改查

(待补充)