數據庫常見問題總結


1.常見的關系型數據庫和非關系型數據庫?

  關系型數據庫(需要表結構):sqllite、db2、oracle、access、SQLserver、MySQL

  非關系型數據庫(key-value結構存儲,沒有表結構):mongodb、redis、memcache

2.常見的數據庫引擎比較?

1>.InnoDB支持事物,而MyISAM不支持事物

2>.InnoDB支持行級鎖,而MyISAM支持表級鎖

3>.InnoDB支持MVCC, 而MyISAM不支持

4>.InnoDB支持外鍵,而MyISAM不支持

5>.InnoDB不支持全文索引,而MyISAM支持。

3.數據庫設計三大范式

第一范式:1NF是對屬性的原子性約束,要求屬性具有原子性,不可再分解;

第二范式:2NF是對記錄的惟一性約束,要求記錄有惟一標識,即實體的惟一性;  

第三范式:3NF是對字段冗余性的約束,即任何字段不能由其他字段派生出來,它要求字段沒有冗余

范式化設計優缺點:

優點:可以盡量得減少數據冗余,使得更新快,體積小

缺點:對於查詢需要多個表進行關聯,減少寫得效率增加讀得效率,更難進行索引優化

4.事務,以及mysql如何支持事務?

'什么是事務'
    事務由一個或多個sql語句組成一個整體;
    在事務中的操作,要么都執行修改,要么都不執行,
    只有在該事務中所有的語句都執行成功才會將修改加入到數據庫中,否則回滾到上一步。
'Mysql實現事務'
    InnoDB支持事務,MyISAM不支持
    # 啟動事務:
        # start transaction;
        # update from account set money=money-100 where name='a';
        # update from account set money=money+100 where name='b';
        # commit;
        'start transaction 手動開啟事務,commit 手動關閉事務'

5.數據庫五大約束

主鍵約束    primary key
默認值約束    default
唯一約束    unique
非空約束    not null
外鍵約束    foreign key

6.mysql索引種類

'主鍵索引(單列)':
    primary key
    加速查找+約束:不能重復、不能為空
'普通索引(單列)':
    加速查找
'唯一索引(單列)':
    unique
    加速查找+約束:不能重復
'聯合索引(多列)':
    查詢時根據多列進行查詢(最左前綴)
'聯合唯一索引(多列)':
    遵循最左前綴規則(命中索引)
# 其他詞語
    1、索引合並:利用多個單列索引查詢
    2、覆蓋索引:在索引表中就能將想要的數據查詢到

7.索引什么情況下遵循最左前綴原則

  聯合索引A,B,C,D

  只要出現A,不管順序如何都會使用索引;只要沒有A,就不會使用索引;

具體用法參考博客:鏈接1

8.創建索引但是無法命中索引的8種情況

#使用'like ‘%xx’'
    select * from tb1 where name like '%cn';
#使用'函數'
    select * from tb1 where reverse(name)='zgc';
#使用'or'
    select * from tb1 where nid=1 or  email='zgc@gmial.com';
    特別的:當or條件中有未建立索引的列才失效,一下會走索引
            # select * from tb1 where nid=1 or name='zgc';
            # select * from tb1 where nid=1 or email='zgc@gmial.com' and name='zgc';
#'類型不一致'
    如果列是字符串類型,傳入條件是必須用引號引起來,不然則可能會無法命中
    select * from tb1 where name=666#含有'!= '
    select * from tb1 where name != 'zgc';
    特別的:如果是主鍵,還是會走索引
            # select * from tb1 where nid != 123;
#含有'>'
    select * from tb1 where name > 'zgc';
    特別的:如果是主鍵或者索引是整數類型,則還是會走索引
            # select * from tb1 where nid > 123;
            # select * from tb1 where name > 123;
#含有'order by'
    select email from tb1 order by name desc;
    當根據索引排序時,選擇的映射如果不是索引,則不走索引
    特別的:如果對主鍵排序,則還是走索引:
            # select * from tb1 order by nid desc;

#組合索引最左前綴
    如果組合索引為:(name,email)
    name and email #使用索引
    name           #使用索引
    email          #不使用索引

9.開啟慢日志查詢

'可以通過修改配置文件開啟'
slow_query_log=ON   #是否開啟慢日志記錄
long_query_time=2   #時間限制,超過此時間,則記錄
slow_query_log_file=/usr/slow.log  #日志文件
long_queries_not_using_indexes=ON  #是否記錄使用索引的搜索

10.數據庫優化方案

1、創建數據表時把固定長度的放在前面
2、將固定數據放入內存:choice字段(django中用到,1,2,3對應相應內容)
3、char不可變,varchar可變
4、聯合索引遵循最左前綴(從最左側開始檢索)
5、避免使用 select *
6、讀寫分離:
    #利用數據庫的主從分離:主,用於刪除、修改、更新;從,用於查
    #實現:兩台服務器同步數據
    \原生SQL:select * from db.tb
    \ORM:model.User.object.all().using('default')
    \路由:d  b router
7、分庫
    # 當數據庫中的表太多,將某些表分到不同數據庫,例如:1W張表時
    # 代價:連表查詢跨數據庫,代碼變多
8、分表
    # 水平分表:將某些列拆分到另一張表,例如:博客+博客詳情
    # 垂直分表:將某些歷史信息,分到另外一張表中,例如:支付寶賬單
9、加緩存
    # 利用redis、memcache(常用數據放到緩存里,提高取數據速度)
    # 緩存不夠可能會造成雪崩現象
10、如果只想獲取一條數據
    select * from tb where name = 'zgc' limit 1;

11.1000w條數據,使用limit offset 分頁時,為什么越往后翻越慢?如何解決?

# 例如:
#limit 100000,20; 從第十萬條開始往后取二十條,
#limit 20 offset 100000; limit后面是取20條數據,offset后面是從第10W條數據開始讀
因為當一個數據庫表過於龐大,LIMIT offset, length中的offset值過大,則SQL查詢語句會非常緩慢
--------------------------------------------------------------------------
'優化一'
先查看主鍵,再分頁:
select * from tb where id in (select id from tb where limit 10 offset 30)
--------------------------------------------------------------------------
'優化二'
記錄當前頁,數據、ID、最大值和最小值(用於where查詢)
在翻頁時,根據條件進行篩選,篩選完畢后,再根據 limit offset 查詢
select * from(select * from tb where id > 2222) as B limit 10 offset 0;
\如果用戶自己修改頁碼,也可能導致變慢,此時可以對 url 頁碼進行加密,例如rest framework
--------------------------------------------------------------------------
'優化三'
可以按照當前業務需求,看是否可以設置只允許看前200頁;
一般情況下,沒人會咔咔看個幾十上百頁的;

12.什么是索引合並?

  索引合並,讓一條sql可以使用多個索引。對這些索引取交集,並集,或者先取交集再取並集。從而減少從數據表中取數據的次數,提高查詢效率。

13.數據庫讀寫分離?

  利用數據庫主從分離,主用來進行數據庫的增添,修改,和刪除操作(INSERT、UPDATE、DELETE)。從用來進行查找操作(SELECT)

  兩台數據庫來同步數據,從而減輕服務器壓力

14.數據路分庫分表操作?

# 1、分庫
    當數據庫中的表太多,將某些表分到不同數據庫,例如:1W張表時
    代價:連表查詢跨數據庫,代碼變多
# 2、分表
    水平分表:將某些列拆分到另一張表,例如:博客+博客詳情
    垂直分表:將某些歷史信息,分到另外一張表中,例如:支付寶賬單

15.如何設計一個高並發的系統?

  數據庫優化,sql語句優化,索引優化

  使用緩存,減少數據庫IO操作

  分布式數據庫,分布式緩存(減輕服務器的壓力)

  服務器的負載均衡

16.鎖的優化策略?

① 讀寫分離

② 分段加鎖

③ 減少鎖持有的時間

④ 多個線程盡量以相同的順序去獲取資源

等等,這些都不是絕對原則,都要根據情況,比如不能將鎖的粒度過於細化,不然可能會出現線程的加鎖和釋放次數過多,反而效率不如一次加一把大鎖。

17.索引的底層實現和原理? 

  B+樹。在所有的葉子結點中增加了指向下一個葉子節點的指針

18.實踐中如何優化mysql?

  sql語句及索引的優化

  表結構優化

  系統配置優化

  硬件優化

19. 簡單描述mysql中,索引,主鍵,唯一索引,聯合索引的區別,對數據庫的性能有什么影響

(1)索引是一種特殊的文件(InnoDB數據表上的索引是表空間的一個組成部分),它們包含着對數據表里所有記錄的引用指針。
(2)普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快對數據的訪問速度。
(3)普通索引允許被索引的數據列包含重復的值,如果能確定某個數據列只包含彼此各不相同的值,在為這個數據索引創建索引的時候就應該用關鍵字UNIQE把它定義為一個唯一所以,唯一索引可以保證數據記錄的唯一性。
(4)主鍵,一種特殊的唯一索引,在一張表中只能定義一個主鍵索引,逐漸用於唯一標識一條記錄,是用關鍵字PRIMARY KEY來創建。
(5)索引可以覆蓋多個數據列,如像INDEX索引,這就是聯合索引。
(6)索引可以極大的提高數據的查詢速度,但是會降低插入刪除更新表的速度,因為在執行這些寫操作時,還要操作索引文件。

20.什么是鎖?

  數據庫是一個多用戶使用的共享資源。當多個用戶並發地存取數據時,在數據庫中就會產生多個事務同時存取同一數據的情況。若對並發操作不加控制就可能會讀取和存儲不正確的數據,破壞數據庫的一致性。

  加鎖是實現數據庫並發控制的一個非常重要的技術。當事務在對某個數據對象進行操作前,先向系統發出請求,對其加鎖。加鎖后事務就對該數據對象有了一定的控制,在該事務釋放鎖之前,其他的事務不能對此數據對象進行更新操作。

  基本鎖類型:鎖包括行級鎖和表級鎖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM