1、列举常见的关系型数据库和非关系型都有那些? 常见关系型数据库:mysql oracle db2 非关系型数据库:mongodb redis 2、MySQL常见数据库引擎及比较? 常用引擎: myisam:不支持事务,支持表锁 innodb:支持事务,支持行锁和表锁 3、简述数据三大范式? 第一:确保每列保持原子性,即每个字段必须是不可拆分的最小单元 例如:创建一个地址的字段时,就应该将其划分为省市区这三个字段,这就满足了上述的原子性。 第二:表中的每列都和主键相关,一个表里只能存在一种数据,不可把多种数据保存在同一张数据库表中。 例如:即订单里存在客户和商品的信息,建议将客户和商品的数据拆分开 即创建两张表 ,一个放订单和客户的信息,一个放订单和商品的信息! 第三:确保每列都和主键直接相关。而不是间接相关。 例如:订单数据表,将客户编号作为一个外键关联字段和订单表建立联系。 而不可以在订单表中添加客户的其他信息。(例如姓名,公司等) 4、什么是事务?MySQL如何支持事务? 是应用程序中一系列严密的操作,所有操作必须成功完成,否则该事务中每个操作都会被撤销。 mysql的事务:存在4个特性:acid 保证数据的安全 start transaction: try: update db set money=100 where name='erha'; update db set money=0 where name = 'enhen'; except: rollback else: commit 5、简述数据库设计中一对多和多对多的应用场景? 一对多:一个用户存在多个订单 多对多:一个订单里有多个商品,一个商品被多个订单包含 6、如何基于数据库实现商城商品计数器? 不写 8、简述触发器、函数、视图、存储过程? 视图:通过定义一个虚拟的表,保存下来,下次直接使用,可以不需要重复查询。 create view 视图 as select * from xxxxx 在硬盘里,视图只存在表结构文件,没有表数据文件。 视图虽说用来查询,但是可以通过修改视图 里的数据来影响原始表的数据。因此尽量不要修改视图里的数据,同时,想去修改数据,还涉及到了跨部门沟通的问题,一般通过修改sql语句去替代。 触发器:在满足所设定的条件下,会在我们对数据库的增删改 的时候自动触发相应的sql语句! create trigger 触发器名字 after insert on 表名 for each row begin sql语句 end 在增加数据之后触发 create trigger 触发器名字 before update on t1 for each row begin sql语句 end 在修改数据之前 事务:保证了我们操作的数据的安全。 四个特性: 原子性,一致性,隔离性,持久性 简称acid 使用: start transaction; 开启事务 try: update user set bala = 90 where name = 'asda'; update user set bala =80 where name = 'dasd'; except: rollback; 回滚 else: commit 只有提交后,数据才能真正写入硬盘 存储过程: 一组可编程的函数,为了完成特定功能的sql语句集,经过编译创建后保存在数据库中,用户可以通过使用指定的存储过程的名字并给定参数时区调用执行。 为什么要用: 1)将重复性很高的一些操作,封装到存储过程里,简化了对sql语句的操作 2)统一了接口,确保数据的安全 不过相对于oracle数据库而言,其的存储过程较弱,使用较少 mysql里的函数: 类似于存储过程,不过其存在返回值 可以自定义函数,也可以直接使用内置函数 常见的内置函数: pi()圆周率 rand()0-1的随机数 round()四舍五入 聚合函数: avg() 平均值 count()计数 min() max() sum() 日期函数: curdata() 当前时间 curtime() 当前日期 9、MySQL索引种类 普通索引:进加速查询 唯一索引:加速查询+列值唯一(可以有null) 主键索引:加速查询+列值唯一(不可以有null)+表中只有一个 组合索引:多列值组成的索引 全文索引:对文本的内容进行分词 10、索引在什么情况下遵循最左前缀的规则? 不想写 11、主键和外键的区别? 主键是用来加速查询的,作为关键字同时唯一确定这条表记录的。二外键是用来关联表之间的关系的 外键的性能问题: 数据库只要维护外键的内部管理 外键等于把数据的一致性事务实现,全部交给数据库服务器完成 当涉及到外键字段的增删,更新操作后,需要触发相关操作去检查,而不得不消耗资源 外键还会因为需要请求对其他表内部加锁而容易出现死锁情况 12、MySQL常见的函数? abs() pi() 圆周率 avg() sum() 13、列举创建索引但是无法命中索引的8种情况。 14、如何开启慢日志查询? 什么是慢查询:mysql提供的一种日志记录,用来记录响应时间超过阀值的sql语句。具体指超过long_query_timme的sql,会被记录到慢查询日志中。其默认值为10秒。 默认是不开启的,需要手动去设定这个参数,如果不是调优需要的话,一般不建议启动该参数。开启的话会带来一定的新能影响。 15、数据库导入导出命令(结构+数据)? 不想弄 16、数据库优化方案? 17、char和varchar的区别? char 为定长字段 ,即给定了位数,不够的话自动空格补全,显示的时候自动将末尾的空格去掉,但是在硬盘里还是按之前的数据存储 varchar 为变长字段 就上述而言,varchar节省硬盘空间,是利用到了给数据加报头来标识数据的长度。 二者的储存方式:char对英文ascii占用1个字节,汉子占用两个字节 varchar英文与汉字均占用两个字节,二者存储的数据类型均非unicode数据类型 18、简述MySQL的执行计划? explain + 查询的sql语句 可以显示sql执行信息的参数,根据参数可以进行sql优化。 19、在对name做了唯一索引前提下,简述以下区别: select * from tb where name = ‘Oldboy-Wupeiqi’ select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1 20、1000w条数据,使用limit offset 分页时,为什么越往后翻越慢?如何解决? limit m n 表示从第m行+1 开始,往后取 n条数据 limit m offset n 表示从第n+1行开始,往后取m条数据 解决思路:先查主键,在分页 select * from db where id in (select id from db limit 10 offset 20) 即查询的时候最好通过传递pk值去减少offset的值,主键最好为int,且具备自增。也可以添加order by,orderby字段需要建立索引。 limit分页优化方法: 1)、子查询优化法 找出第一条数据,大于等于这条数据的id就是想要获取的数据 缺点:数据必须为连续的,可以说不能存在where条件,因其会筛选数据,导致数据失去连续性。一般而言,偏移量在1000以上使用子查询可以有效提高性能 2)、limit限制优化法 把limit偏移量限制为低于摸个数。超过这个数据没得数据。记得alibab的dba是这样做的。 21、什么是索引合并? 22、什么是覆盖索引? 23、简述数据库读写分离? 其实就是将数据库分为了主从库,一个用来写数据,其他多个完成读的操作。 二者之间通过某种机制实现数据同步,常见的数据库架构。 大多数互联网业务,读多写少,数据库的读会先成为数据库的瓶颈,往往希望提高数据库的读性能,清除读写锁冲突从而提升数据库的写性能,采用读写分离架构。 一句话,读写分离是用来解决数据库的读性能瓶颈的。 在实际的应用场景下,数据量大,高并发,高可用,高一致性,需要注意: 区分数据库是读,还是写,研发的难度增加 还得要实现读连接池的故障自动转移 主从的一致性需要考虑。 可以的话,先去考虑使用缓存。这是一种常见的架构。读写分离是通过读多个数据库分担数据库读压力,缓存是通过对缓存的使用来减少读数据库的读压力。 为什么:缓存的使用成本比从库少, 缓存的开发容易,大部分的读操作都可以先去缓存,找不到再去数据库查找。 如果退一步说,使用缓存后任然无法解决读的瓶颈时,可以选择读写分离架构。 说道缓存,必须考虑的是高可用性,不然缓存一旦挂了,所有的流量同时聚集在数据库上,会造成缓存雪崩的现象。 常见的数据库瓶颈其实是数据容量的瓶颈。例如 订单表,数量只增不减,历史数据要留存,非常容易造成性能的瓶颈,对于这样的问题,读写分离和缓存往往都不合适,合理的做法应该是数据库库水平切分。 作为一种常见的数据库架构,是一种通过算法,将数据库进行分割的架构。 一个水平切分集群中的每个数据库,通常为一个分片。每个分片的数据没有重合,所有分片里的数据并集组成全部的数据。 提高数据库的写性能,降低单库容量,采用水平切分。 24、简述数据库分库分表?(水平、垂直) 数据库分库:把一堆数据放到不同的数据库中保存 数据库分表: 垂直切分:不同功能,不同模块的数据放到不同的表中,同一模块的数据量太大会照成性能瓶颈。 水平切分:垂直切分解决不了大表的瓶颈,同一个表中数据量过大,需要对其水平切分 简单理解:垂直切分是分为不同的模块表 水平切分是同一模块下的多个表 25、sql注入攻击原理,代码成面实现防止sql注入 原理:通过前段的表单提交的数据中携带sql语句,欺骗服务器,在后端对数据库进行存储时,执行恶意的sql语句。 出现的地方: 在使用pymysql模块时,操作数据库是是使用字符串拼接产生的sql语句,就会出现sql注入漏洞。 防止: 使用pymysql时,不要使用字符串拼接,而是使用execute的方法,pymysql 的模块已经对数据进行了处理,不会出现sql注入 永远不要相信前端提交的任何数据,要严格校验 不要把机密的信息中介存放,而要进过加密以后存放。 不要使用管理员权限的数据库进行连接,为每个应用使用单独的权限进行数据库连接。