# 创建数据库脚本

# 1. 关于创建数据库

创建数据库的语法是:

CREATE DATABASE 数据库名称;
1

当某个项目规模特别大时,应该根据数据之间的关系,尽可能的拆为多个数据库。

# 2. 关于使用数据库

使用数据库的语法是:

USE 数据库名称;
1

提示:以上语法中的分号是可选的。

# 3. 创建数据表

创建数据表的基本语法是:

CREATE TABLE 数据表名称 (字段设计列表) CHARSET 字符编码 COMMENT 注释;
1

注意:主流的设计中,数据表的编码强烈建议配置为utf8mb4(过低版本的MySQL不支持)。

在设计字段时,基本语法是:

字段名 字段类型 字段约束 comment 注释
1

简单示例:

create table ams_admin (
    id bigint unsigned auto_increment,
    username varchar(50) default null unique comment '用户名',
    password char(64) default null comment '密码(密文)',
    nickname varchar(50) default null comment '昵称',
    avatar varchar(255) default null comment '头像URL',
    phone varchar(50) default null unique comment '手机号码',
    email varchar(50) default null unique comment '电子邮箱',
    description varchar(255) default null comment '描述',
    is_enable tinyint unsigned default 0 comment '是否启用,1=启用,0=未启用',
    last_login_ip varchar(50) default null comment '最后登录IP地址(冗余)',
    login_count int unsigned default 0 comment '累计登录次数(冗余)',
    gmt_last_login datetime default null comment '最后登录时间(冗余)',
    gmt_create datetime default null comment '数据创建时间',
    gmt_modified datetime default null comment '数据最后修改时间',
    primary key (id)
) comment '管理员表' charset utf8mb4;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

关于以上设计:

  • 自动编号的id应该是bigint unsigned类型的,以确保id够用
    • MySQL中的整形类型:tinyintsmallintintbigint
  • 关于varchar的使用,必须设置长度,建议设置为比合理的最大值更大一些的值,例如规则为“用户名最多16字符”,则varchar中设置的字符长度最少20
  • 永远不要使用not null约束,任何你认为必须的字段,以后都可能不是必须的
  • 相对固定长度的字符串类型应该使用char,而不是使用varchar
    • 并不要求每个数据的长度完全一致
    • char的读取效率略高于varchar,占用的空间可能比varchar少1~2个字节
-- 数据库:mall_pms

-- 相册表:创建数据表
drop table if exists pms_album;
create table pms_album
(
    id           bigint unsigned auto_increment comment '记录id',
    name         varchar(50)      default null comment '相册名称',
    description  varchar(255)     default null comment '相册简介',
    sort         tinyint unsigned default 0 comment '自定义排序序号',
    gmt_create   datetime         default null comment '数据创建时间',
    gmt_modified datetime         default null comment '数据最后修改时间',
    primary key (id)
) comment '相册' charset utf8mb4;

-- 相册表:为相册名称字段添加索引
create index idx_album_name on pms_album (name);

-- 图片表:创建数据表
drop table if exists pms_picture;
create table pms_picture
(
    id           bigint unsigned auto_increment comment '记录id',
    album_id     bigint unsigned   default null comment '相册id',
    url          varchar(255)      default null comment '图片url',
    description  varchar(255)      default null comment '图片简介',
    width        smallint unsigned default null comment '图片宽度,单位:px',
    height       smallint unsigned default null comment '图片高度,单位:px',
    is_cover     tinyint unsigned  default 0 comment '是否为封面图片,1=是,0=否',
    sort         tinyint unsigned  default 0 comment '自定义排序序号',
    gmt_create   datetime          default null comment '数据创建时间',
    gmt_modified datetime          default null comment '数据最后修改时间',
    primary key (id)
) comment '图片' charset utf8mb4;

-- 品牌表:创建数据表
drop table if exists pms_brand;
create table pms_brand
(
    id                     bigint unsigned auto_increment comment '记录id',
    name                   varchar(50)      default null comment '品牌名称',
    pinyin                 varchar(50)      default null comment '品牌名称的拼音',
    logo                   varchar(255)     default null comment '品牌logo的URL',
    description            varchar(255)     default null comment '品牌简介',
    keywords               varchar(255)     default null comment '关键词列表,各关键词使用英文的逗号分隔',
    sort                   tinyint unsigned default 0 comment '自定义排序序号',
    sales                  int unsigned     default 0 comment '销量(冗余)',
    product_count          int unsigned     default 0 comment '商品种类数量总和(冗余)',
    comment_count          int unsigned     default 0 comment '买家评论数量总和(冗余)',
    positive_comment_count int unsigned     default 0 comment '买家好评数量总和(冗余)',
    enable                 tinyint unsigned default 0 comment '是否启用,1=启用,0=未启用',
    gmt_create             datetime         default null comment '数据创建时间',
    gmt_modified           datetime         default null comment '数据最后修改时间',
    primary key (id)
) comment '品牌' charset utf8mb4;

-- 品牌表:为品牌名称字段添加索引
create index idx_brand_name on pms_brand (name);

-- 类别表:创建数据表
drop table if exists pms_category;
create table pms_category
(
    id           bigint unsigned auto_increment comment '记录id',
    name         varchar(50)      default null comment '类别名称',
    parent_id    bigint unsigned  default 0 comment '父级类别id,如果无父级,则为0',
    depth        tinyint unsigned default 1 comment '深度,最顶级类别的深度为1,次级为2,以此类推',
    keywords     varchar(255)     default null comment '关键词列表,各关键词使用英文的逗号分隔',
    sort         tinyint unsigned default 0 comment '自定义排序序号',
    icon         varchar(255)     default null comment '图标图片的URL',
    enable       tinyint unsigned default 0 comment '是否启用,1=启用,0=未启用',
    is_parent    tinyint unsigned default 0 comment '是否为父级(是否包含子级),1=是父级,0=不是父级',
    is_display   tinyint unsigned default 0 comment '是否显示在导航栏中,1=启用,0=未启用',
    gmt_create   datetime         default null comment '数据创建时间',
    gmt_modified datetime         default null comment '数据最后修改时间',
    primary key (id)
) comment '类别' charset utf8mb4;

-- 类别表:为类别名称字段添加索引
create index idx_category_name on pms_category (name);

-- 品牌类别关联表:创建数据表
drop table if exists pms_brand_category;
create table pms_brand_category
(
    id           bigint unsigned auto_increment comment '记录id',
    brand_id     bigint unsigned default null comment '品牌id',
    category_id  bigint unsigned default null comment '类别id',
    gmt_create   datetime        default null comment '数据创建时间',
    gmt_modified datetime        default null comment '数据最后修改时间',
    primary key (id)
) comment '品牌与类别关联' charset utf8mb4;

-- 属性表:创建数据表
drop table if exists pms_attribute;
create table pms_attribute
(
    id                 bigint unsigned auto_increment comment '记录id',
    template_id        bigint unsigned  default null comment '所属属性模版id',
    name               varchar(50)      default null comment '属性名称',
    description        varchar(255)     default null comment '简介(某些属性名称可能相同,通过简介补充描述)',
    type               tinyint unsigned default 0 comment '属性类型,1=销售属性,0=非销售属性',
    input_type         tinyint unsigned default 0 comment '输入类型,0=手动录入,1=单选,2=多选,3=单选(下拉列表),4=多选(下拉列表)',
    value_list         varchar(255)     default null comment '备选值列表',
    unit               varchar(50)      default null comment '计量单位',
    sort               tinyint unsigned default 0 comment '自定义排序序号',
    is_allow_customize tinyint unsigned default 0 comment '是否允许自定义,1=允许,0=禁止',
    gmt_create         datetime         default null comment '数据创建时间',
    gmt_modified       datetime         default null comment '数据最后修改时间',
    primary key (id)
) comment '属性' charset utf8mb4;

-- 属性模版表:创建数据表
drop table if exists pms_attribute_template;
create table pms_attribute_template
(
    id           bigint unsigned auto_increment comment '记录id',
    name         varchar(50)      default null comment '属性模版名称',
    pinyin       varchar(50)      default null comment '属性模版名称的拼音',
    keywords     varchar(255)     default null comment '关键词列表,各关键词使用英文的逗号分隔',
    sort         tinyint unsigned default 0 comment '自定义排序序号',
    gmt_create   datetime         default null comment '数据创建时间',
    gmt_modified datetime         default null comment '数据最后修改时间',
    primary key (id)
) comment '属性模版' charset utf8mb4;

-- 属性模版表:为属性模版名称字段添加索引
create index idx_attribute_template_name on pms_attribute_template (name);

-- 类别与属性模版关联表:创建数据表
drop table if exists pms_category_attribute_template;
create table pms_category_attribute_template
(
    id                    bigint unsigned auto_increment comment '记录id',
    category_id           bigint unsigned default null comment '类别id',
    attribute_template_id bigint unsigned default null comment '属性模版id',
    gmt_create            datetime        default null comment '数据创建时间',
    gmt_modified          datetime        default null comment '数据最后修改时间',
    primary key (id)
) comment '类别与属性模版关联' charset utf8mb4;

-- SPU(Standard Product Unit)表:创建数据表
drop table if exists pms_spu;
create table pms_spu
(
    id                     bigint unsigned not null comment '记录id',
    name                   varchar(50)      default null comment 'SPU名称',
    type_number            varchar(50)      default null comment 'SPU编号',
    title                  varchar(255)     default null comment '标题',
    description            varchar(255)     default null comment '简介',
    list_price             decimal(10, 2)   default null comment '价格(显示在列表中)',
    stock                  int unsigned     default 0 comment '当前库存(冗余)',
    stock_threshold        int unsigned     default 0 comment '库存预警阈值(冗余)',
    unit                   varchar(50)      default null comment '计件单位',
    brand_id               bigint unsigned  default null comment '品牌id',
    brand_name             varchar(50)      default null comment '品牌名称(冗余)',
    category_id            bigint unsigned  default null comment '类别id',
    category_name          varchar(50)      default null comment '类别名称(冗余)',
    attribute_template_id  bigint unsigned  default null comment '属性模版id',
    album_id               bigint unsigned  default null comment '相册id',
    pictures               varchar(500)     default null comment '组图URLs,使用JSON数组表示',
    keywords               varchar(255)     default null comment '关键词列表,各关键词使用英文的逗号分隔',
    tags                   varchar(255)     default null comment '标签列表,各标签使用英文的逗号分隔,原则上最多3个',
    sales                  int unsigned     default 0 comment '销量(冗余)',
    comment_count          int unsigned     default 0 comment '买家评论数量总和(冗余)',
    positive_comment_count int unsigned     default 0 comment '买家好评数量总和(冗余)',
    sort                   tinyint unsigned default 0 comment '自定义排序序号',
    is_deleted             tinyint unsigned default 0 comment '是否标记为删除,1=已删除,0=未删除',
    is_published           tinyint unsigned default 0 comment '是否上架(发布),1=已上架,0=未上架(下架)',
    is_new_arrival         tinyint unsigned default 0 comment '是否新品,1=新品,0=非新品',
    is_recommend           tinyint unsigned default 0 comment '是否推荐,1=推荐,0=不推荐',
    is_checked             tinyint unsigned default 0 comment '是否已审核,1=已审核,0=未审核',
    check_user             varchar(50)      default null comment '审核人(冗余)',
    gmt_check              datetime         default null comment '审核通过时间(冗余)',
    gmt_create             datetime         default null comment '数据创建时间',
    gmt_modified           datetime         default null comment '数据最后修改时间',
    primary key (id)
) comment 'SPU(Standard Product Unit)' charset utf8mb4;

-- SPU详情表:创建数据表
drop table if exists pms_spu_detail;
create table pms_spu_detail
(
    id           bigint unsigned auto_increment comment '记录id',
    spu_id       bigint unsigned default null comment 'SPU id',
    detail       text            default null comment 'SPU详情,应该使用HTML富文本,通常内容是若干张图片',
    gmt_create   datetime        default null comment '数据创建时间',
    gmt_modified datetime        default null comment '数据最后修改时间',
    primary key (id)
) comment 'SPU详情' charset utf8mb4;

-- SKU(Stock Keeping Unit)表:创建数据表
drop table if exists pms_sku;
create table pms_sku
(
    id                     bigint unsigned not null comment '记录id',
    spu_id                 bigint unsigned  default null comment 'SPU id',
    title                  varchar(255)     default null comment '标题',
    bar_code               varchar(255)     default null comment '条型码',
    attribute_template_id  bigint unsigned  default null comment '属性模版id',
    specifications         varchar(2500)    default null comment '全部属性,使用JSON格式表示(冗余)',
    album_id               bigint unsigned  default null comment '相册id',
    pictures               varchar(500)     default null comment '组图URLs,使用JSON格式表示',
    price                  decimal(10, 2)   default null comment '单价',
    stock                  int unsigned     default 0 comment '当前库存',
    stock_threshold        int unsigned     default 0 comment '库存预警阈值',
    sales                  int unsigned     default 0 comment '销量(冗余)',
    comment_count          int unsigned     default 0 comment '买家评论数量总和(冗余)',
    positive_comment_count int unsigned     default 0 comment '买家好评数量总和(冗余)',
    sort                   tinyint unsigned default 0 comment '自定义排序序号',
    gmt_create             datetime         default null comment '数据创建时间',
    gmt_modified           datetime         default null comment '数据最后修改时间',
    primary key (id)
) comment 'SKU(Stock Keeping Unit)' charset utf8mb4;

-- SKU规格参数表(存储各SKU的属性与值,即规格参数):创建数据表
drop table if exists pms_sku_specification;
create table pms_sku_specification
(
    id              bigint unsigned auto_increment comment '记录id',
    sku_id          bigint unsigned  default null comment 'SKU id',
    attribute_id    bigint unsigned  default null comment '属性id',
    attribute_name  varchar(50)      default null comment '属性名称',
    attribute_value varchar(50)      default null comment '属性值',
    unit            varchar(10)      default null comment '自动补充的计量单位',
    sort            tinyint unsigned default 0 comment '自定义排序序号',
    gmt_create      datetime         default null comment '数据创建时间',
    gmt_modified    datetime         default null comment '数据最后修改时间',
    primary key (id)
) comment 'SKU数据' charset utf8mb4;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

# 附:关于密码加密

在基于Maven的项目中添加以下依赖:

<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>
1
2
3
4
5
6

对密码进行加密,可以有效的保障密码安全,即使出现数据库泄密,密码安全也不会受到影响!为了实现此目标,需要在对密码进行加密时,使用不可逆的算法进行处理!

通常,不可以使用加密算法对密码进行加密码处理,从严格定义上来看,所有的加密算法都是可以逆向运算的,即同时存在加密和解密这2种操作,加密算法只能用于保证传输过程的安全,并不应该用于保证需要存储下来的密码的安全!

哈希算法都是不可逆的,通常,用于处理密码加密的算法中,典型的是一些消息摘要算法,例如MD5、SHA256或以上位数的算法。

消息摘要算法的主要特征有:

  • 消息相同时,摘要一定相同
  • 某种算法,无论消息长度多少,摘要的长度是固定的
  • 消息不同时,摘要几乎不会相同

在消息摘要算法中,以MD5为例,其运算结果是一个128位长度的二进制数,通常会转换成十六进制数显示,所以是32位长度的十六进制数,MD5也被称之为128位算法。理论上,会存在2的128次方种类的摘要结果,且对应2的128次方种不同的消息,如果在未超过2的128次方种消息中,存在2个或多个不同的消息对应了相同的摘要,则称之为:发生了碰撞。一个消息摘要算法是否安全,取决其实际的碰撞概率,关于消息摘要算法的破解,也是研究其碰撞概率。

存在穷举消息和摘要的对应关系,并利用摘要在此对应关系进行查询,从而得知消息的做法,但是,由于MD5是128位算法,全部穷举是不可能实现的,所以,只要原始密码(消息)足够复杂,就不会被收录到所记录的对应关系中去!

为了进一步提高密码的安全性,在使用消息摘要算法进行处理时,通常还会加盐!盐值可以是任意的字符串,用于与密码一起作为被消息摘要算法运算的数据即可,例如:

@Test
public void md5Test() {
    String rawPassword = "123456";
    String salt = "kjfcsddkjfdsajfdiusf8743urf";
    String encodedPassword = DigestUtils.md5DigestAsHex(
            (salt + salt + rawPassword + salt + salt).getBytes());
    System.out.println("原密码:" + rawPassword);
    System.out.println("加密后的密码:" + encodedPassword);
}
1
2
3
4
5
6
7
8
9

加盐的目的是使得被运算数据变得更加复杂,盐值本身和用法并没有明确要求!

甚至,在某些用法或算法中,还会使用随机的盐值,则可以使用完全相同的原消息对应的摘要却不同!

推荐了解:预计算的哈希链、彩虹表、雪花算法。

为了进一步保证密码安全,还可以使用多重加密,即反复调用消息摘要算法。

除此以外,还可以使用安全系数更高的算法,例如SHA-256是256位算法,SHA-384是384位算法,SHA-512是512位算法。

一般的应用方式可以是:

public class PasswordEncoder {

    public String encode(String rawPassword) {
        // 加密过程
        // 1. 使用MD5算法
        // 2. 使用随机的盐值
        // 3. 循环5次
        // 4. 盐的处理方式为:盐 + 原密码 + 盐 + 原密码 + 盐
        // 注意:因为使用了随机盐,盐值必须被记录下来,本次的返回结果使用$分隔盐与密文
        String salt = UUID.randomUUID().toString().replace("-", "");
        String encodedPassword = rawPassword;
        for (int i = 0; i < 5; i++) {
            encodedPassword = DigestUtils.md5DigestAsHex(
                    (salt + encodedPassword + salt + encodedPassword + salt).getBytes());
        }
        return salt + encodedPassword;
    }

    public boolean matches(String rawPassword, String encodedPassword) {
        String salt = encodedPassword.substring(0, 32);
        String newPassword = rawPassword;
            for (int i = 0; i < 5; i++) {
                newPassword = DigestUtils.md5DigestAsHex(
                        (salt + newPassword + salt + newPassword + salt).getBytes());
        }
        newPassword = salt + newPassword;
        return newPassword.equals(encodedPassword);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30