主键的选择
- 建一个id列,将id设为主键并且id列是自增的
- 订单表的订单号
- 主键主要分两类:
- 代理主键:与业务无关,无意义的数字序列(与业务无关)
- 自然主键:事务属性中的自然唯一标识(与业务挂钩)
- 自然主键每一张表都对应着一个实体 类—->ORM模型
- 推荐使用代理主键
- 因为不与业务耦合,更容易维护
- 一个大多数表(全部表)通用的键策略能够减少需要编写的源码数量,**减少系统的总体拥有成本**
- 比如用UUID—->主键生成器(项目庞大要写)
- 主键生成器表示自己定义的一个策略,不允许重复,但是和UUID不一样,有n种的生成策略;当指定了一种生成策略之后,所有的其他表都可以进行引用,这样写代码的时候维护成本更低一点;假如用自然主键(与业务逻辑相关的主键)时,维护起来就比较麻烦了,维护成本就会上升
- Oracle中没有自增,就只是创建了一个序列Sequence—->序列可以指定最小值和最大值,可以指定从哪个值开始,也可以指定每次增长的个数是多少(可以不每次增长1),步长可以按照自己的方式来进行整合(自己的策略)
- 建议使用一个统一的策略,这样维护起来比较容易一些,成本也随之下降了
- 公司中没有权限设计表就算了,有权限的话就可以用代理主键(自定义主键生成器),使用的统一策略方便维护
字符集的选择
- 🌟中文选utf-8时,只能存储两个字节(字符???)的中文,如果是3个的话,就不能存了,会出现乱码
- 在公司中存中文的时候不建议设置成utf-8
- mysql对utf-8这种编码格式是有要求的,用的是2-3个字节来存储字符的
- 在linux中学习utf-8
yum install man man-pages
—->文档安装 man utf8
orman utf-8
orman 2 utf8
- 因此在mysql中要存储中文的时候,建议设置成utf8mb64格式
- 纯拉丁文默认是latin1,不设置的话
- 纯拉丁字符能表示的内容,没必要选择latin1之外的其他字符编码,这样会节省大量的存储空间
- 可以确定不存放多种语言,可以不选择utf8或者其他unicode字符类型,会造成大量的存储空间浪费
- mysql数据类型可以精确到字段,可以对不同表的不同字段使用不同的数据类型来减小数据存储量,进而降低IO操作次数并提高缓存命中率(在需要大型数据库中存放多字节数据的情形中!)
- gbk在一般情况下不常用,一般情况下不用,没写过不知道会出现什么问题(可以改掉,或者试一试)
- utf8mb4是最常用的一种方式(utf8mb64???)
- utf8算是mysql的一个bug❓❓❓
- 用gbk就是作死❓(什么bug)
存储引擎的选择
- 不做任何设置的时候默认是innodb的
- 在mysql的配置文件中可以修改这个默认值(my.inf—->windows)
default-storage-engin=INNODB
- 单独建表的时候可以指定ENGIN=MyIsam
- 最主要的是衡量Innodb和myisam两种存储引擎之间的区别
- memory也有人在用,但是memory有问题—->不能进行持久化
- performance_schema存储引擎
- 最开始的时候只有myisam,后来以插件的形式引入了innodb
- innnodb比较好
- 锁的粒度:mysiam指支持表锁,innodb既支持行锁又支持表锁
- 如何区分表锁还是行锁?
- innodb默认情况下是给**索引**加锁的,只需要在数据查询、分析(增删改查操作)的时候,去看所写的条件列是不是建索引的列
- 是的话就用行锁
- 不是的话就用表锁
- 之后对锁进行学习
- 🌟全文索引:用来找content列中的一段很长的数据中的某些关键字(比如找一下java关键字),取出“java”关键字
- 企业中一般很少用这个全文索引,因为效率比较低,一般用luson、solr、es(按时间先后,发展变化)
- 不用lat,lat是模糊匹配的方式,并且他有问题
- 讲索引的时候会讲lat的问题
- 现在企业中更多用的是es
- 倒排索引:一般在搜索引擎中用的是倒排索引
- lat可能用不上索引,假如在子句中写的是百分号开头的话,索引是用不上的
- es效率比较高
- select多的用myisam,insert、delete、update多的话用innodb
- 没有明确的限制,不确定的时候用innodb就行了
- 事务、锁、索引都是跟存储引擎相关的
- 存储引擎的意思:数据文件的组织形式
- 数据文件的组织形式不一样,进行数据查询或者数据的增删改查的时候进行的操作就不一样了,所以所有的操作都是与存储引擎相关的
- 存储引擎很重要!!!
- hive官网—->不同格式有不同的修改
- 后期可以改变存储引擎,但是需要将innodb或者myisam进行一个互通转换,比如索引、列的一些东西,要进行转换,有很多要注意的点,一般没人干这个事—->成本太高了
适当的数据冗余
- 被频繁引用并且只能通过join2张(或者更多)表的方式才能得到的独立小字段
- join的成本非常高
- 把要用到的列单独拿出来作为一张表,降低查询的成本
- 成立为单独的物理表之后,表中的数据要进行一个持久的更新
- 不更新就有问题了
- 视图—->物化视图(Oracle中有,MySQL中没有)
- join到的记录比较大,会造成不必要的IO—->用空间来换时间
- 视图只是定义一个sql语句,每次要用视图的时候,提前把sql语句执行一次
- 而物化视图指的是将sql语句执行的结果会提前放到一张物理表中,基表数据更新了,当前的物化视图也要进行更改
- Oracle中提供了两种机制
- onCommit:每次基表中的数据更新了就将物化视图中的数据进行更改
- onDemand:有查询需求的时候才会将这个表进行更改,可以选择不同的方式
- MySQL中没有物化视图,但是同样也要进行更新,不update的话就有问题了(数据不一致的问题)
- 确保数据的一致性不会遭到破坏,确保冗余字段也被更新(冗余数据的更新)
- 有点类似缓存,但是不太对,因为缓存效率比较高,但是物化视图还是从磁盘IO,效率并没有太大的提升,只是省去了大部分的join连接的时间
- 冗余数据可以用触发器修改
适当拆分
- 分库分表—->垂直切分、水平切分
- 垂直切分:根据对应的实际业务来切分,有很多张表,可以按照不同业务把不同的表放到不同的物理服务器中,请求会被分担到不同的物理服务器中,可以减轻单台服务器的压力
- 水平切分:一张表中有很多字段,可以按照某一个字段的范围划分;比如1-1000放一台服务器上,1001-2000放到另外一台服务器上……
- 按照自己的实际业务来决定自己到底按什么样的方式进行切分
- MyCat—->Sharding rule切分规则
- 公司技术转型、技术重构—->尤其是数据库方面的
- 要将传统项目,耦合性较高的项目拆分出来的时候切分非常重要
- 有可能拆分失败,会把业务都拆分得稀烂
- 舆情系统:给一些公关公司、政府机构做一些舆情监控
- 爬虫**,爬完之后分词做一些情感分析**
- 然后给用户发一个通知
- 爬虫不难,难在情感分析—->这个中文词是什么情感在里面(正向、积极的还是负向的、消极的还是中性的)
- 往AWS进行迁移的时候,拆业务很难(亚马逊)
- 数据库的(业务)切分是真的非常非常麻烦的,一般情况下比较ex
- AWS亚马逊培训案例—->爱奇艺上云了—->AWS
- 用爱奇艺的例子讲解上云的时候如何做业务切分、数据切分
- 爱奇艺在往云上上的时候做业务切分很难受、很麻烦
- 这里的适当切分指的是一张表中字段的切分
- 当我们的表中存在类似于TEXT或者是很大的VARCHAR类型的大字段的时候,如果我们大部分访问这张表的时候都不需要这个字段,我们就该义无反顾的将其拆分到另外的**独立表**中,以减少常用数据所占用的存储空间。这样做的一一个明显好处就是每个数据块中可以存储的数据条数可以大大增加,既减少物理IO次数,也能大大提高内存中的缓存命中率。
- 假如一个表中有n多个字段—->100个字段,经常用的也就10个、二十几个、三十几个,剩下的字段一般情况下用不到
- 用不到的时候就占用了比较大的存储空间,这时就可以把不经常用的数据拆分出来,如果要查的时候做一次关联的时候就可以了,不要的时候就直接查就行了
- 这种情况在公司业务量比较大,表里面东西比较多(列比较多、字段比较多)的时候必须要去做的,因为查询效率会成倍提升
- 在查询数据库的时候,如果索引建得比较优秀还好,如果索引建得不好的话(没按索引进行查询的话),就得进行一个匹配,这个匹配过程是非常耗时间的
- 数据库设计得不好简直就是灾难
- 公司中业务庞大的时候就需要进行拆分
- 如何优秀(优化)?
- 看数据库的设计,记录下经常查询的数据(sql语句),有哪些sql执行比较多,常用的列是哪些,把常用的列单独拿出来就行,把不常用的列踢出去
- 索引的优化—->技术难点(单独专题)—->重要