SQL 基礎學習(1):下載DB Browser for SQLite. 下載graphviz(爲了使用Rails ERD的前提)出現❌,已debug.

SQL is a standard language for storing, manipulating and retrieving data in databases.html

 

關係型數據庫:RDBMS(Relational Database Mangement System) mysql

 

SQLite3:git

Rails默認的輕量級數據庫,集成於Rails中,在db/development.sqlite3這個檔案中。github

用途:單機用途。因此在實際部署的時候會換成MySQL等數據庫服務器。 sql

 

MySQL: 數據庫

 目前流行的開源數據庫。這是一個數據庫服務器,要鏈接它須要數據庫的帳號密碼。服務器

 Mac上用 brew install mysql 安裝MySQL,推薦再安裝 Sequal Pro 這套Gui(Graphical User interface,圖形用戶界面)軟件 併發

 


若是有人問你數據庫的原理,叫他看這篇文章http://blog.jobbole.com/100349/ 

一些進修學習資料:app


 

rdbms的特色:數據庫設計

Relationship database mangement system: 

一 schema:使用前先定義tables和columns,同時定義每一個column的Data Type.

Data Type:

varchar或text: 

Integer,Decimal,Float:

Blob二進制:能夠存放檔案。可是一般不建議把檔案直接塞數據庫,一來數據庫塞太大不容易備份和管理、二來沒有什麼好處,由於你也沒辦法針對二進制檔案進行條件搜尋和過濾。人們對於讀檔案也有心理準備會比較慢。因此一般只會在數據庫裏面紀錄檔案的 metadata 例如檔名、大小、MimeType 等等,而實際的檔案則放在檔案系統上,或是上傳到七牛或AWS S3等空間。

Boolean:

Date, Time, Datetime:

create_table :events do |t|
t.string :name
t.text :description
t.integer :capacity
t.integer :user_id, :null => false //這個是限制constraint,這裏是不能爲空;
大多驗證通常放在rails model中,這樣比較有彈性,在DB層是硬性條件,沒法跳過。
t.timestamps
end

 

二 SQL standard language (Structured Query Language)

全部關係型數據庫都使用SQL的結構化查詢語言,來操做database.for example:

1. INSERT INTO events VALUES ("RubyConf", 100);   //插入一條數據到events表

2. SELECT * FROM events;  //拿出全部數據

 

三 ACID(4個特性) 

 Transaction:a process of doing business.把一組動做打包一塊兒執行。使用BEGIN;...COMMIT;   能夠保證數據存取的正確性;要麼一塊兒成功,要麼一塊兒失敗。

Atomicity: 一個transaction就是一個原子。

Consistency:一致性,保證transaction先後數據庫的完整性沒有被破壞。

Isolation:隔離性:數據庫容許多個併發的transaction同時進行,互不干擾。 

Durability持久性:數據的修改是永久的。
 這4個特性,讓關係型數據庫在多人連線操做數據庫的時候,保證數據的✅。

 


 

 

基礎SQL(Structured Query Language) 

 SQL 分爲DDL(Data Definition Language)定義,和DML(Data Manipulation Language)操做。

 

 一 DDLteach us How to definate Schema. 老師建議用GUi(graphical user interface)軟件.

⚠️  :創建database的時候,選擇Encoding. MySQL可用utf8mb4編碼。

打開數據庫:SQLite3: 在Terminal用cli指令打開 sqlite3 your_db_name.db 

MySQL 的話,指令是  mysql -u root -p。PostgreSQL 的指令是  psql <database_name>

 一個gul :  http://sqlitebrowser.org/

 

創建table: 

 CREATE TABLE events (name VARCHAR(50) NOT NULL, capacity INTEGER, date DATE);

更名: ALTER TABLE persons RENAME TO people;

新增字段: ALTER TABLE people ADD COLUMN status VARCHAR(50); 

修改和移除字段:sqlite3沒有支援,須要新開一個table而後複製過去。 

 

Migration機制:

經過migration的功能修改數據庫,在開機時堅持當前的版本和database裏的版本是否一致。同時migration代碼會放到Git裏面,方便整個開發團隊的開發者在不一樣的服務器上,利用migration來一致管理Schema.

這個功能就是你們熟悉的Rails Migration. 

 

二 SQL 語言 :DML

:就是作crud操做。 

新增資料用insert into

 INSERT INTO events(capacity, name) VALUES(200,"Jdstore");

至關於Rails語法:Event.create(capacity:200, name:"Jdstore") 

//也能夠插入多筆

 INSERT INTO events(capacity, name) VALUES(300,"coscup"), (200, ''hello");

查找資料用select * from table_name ORDER BY column_name ASC LIMIT 20 OFFSET 10;

order by:設定排序

limit 20: 設定最多返回20條record

offset 10: 設定按照設定好的順序,從第十一條record撈取。 必須和limit配合使用。

 

修改資料 用UPDATE table_name SET column_name = value;

對應的Rails: Tablename.update_all(:column_name => value);

 

WHERE column_name = "value";  //用where來指定修改的條件。例子:

SQL:  UPDATE events SET capacity=200 WHERE name="chentianwei";對應的rails語法見下:

Rails: Event.where(:name => "chentianwei").update_all(:capacity => 200); 

 

WHERE .. BETWEEN .. AND ..; 某個區間SELECT * FROM events WHERE date BETWEEN '2015-03-15' AND '2015-03-30';

WHERE .. OR ..  條件或

WHERE..AND..   條件且

WHERE .. LIKE.. 模糊對比:SELECT * FROM events WHERE name LIKE '%Ruby%';

WHERE .. IS NOT NULL 不可爲空

WHERE .. IN  也是一個範圍選擇 :

SELECT * FROM Employees WHERE LastName IN ('Smith' , 'Doe');  

對比時,注意大小寫,每一個數據庫默認不同,MySQL是 case insensitive不敏感。 

 

在Rails中比較常見的:

@event = Event.find(21)

@event.update(:capacity => 200)

對應的SQL:

SELECT * FROM events WHERE id=21;

UPDATE events SET capacity=200 WHERE id=21; 

 

刪除數據: 

DELETE FROM table_name;所有刪除,對應的rails語法是Table_name.delete_all 

 例子:

SQL:  DELETE FROM events WHERE name="RubyConf";

Rails:   Event.where(:name => "RubyConf").delete_all 

 

在rails中常見的是:

@event = Event.find(123)

@event.destroy

對應的SQL是:

SELETE * FROM events WHERE id=123;

DELETE FROM events WHERE id=123;

 

查有哪些tables和columns,各家語法不同:

mysql: show tables 和 describe tablename

sqlite3: .tables 和 .schema tablename

PostgreSQL:  \dt 和 \dt tablename

在Rails console: Table_name.columns 會反射出有哪些字段。 

 

Indexes

WHERE ,ORDER等條件字段最好加上數據庫索引,這樣搜索速度快。

  • 加索引 CREATE INDEX events_user_id_idx ON events(user_id);
  • 索引而且值是惟一 CREATE UNIQUE INDEX xxx_idx ON xxx(yyy); 

LIKE模糊查詢是Full Table Scan,幾萬筆數據內還能接受,再大就要用搜索引擎了,如ElasticSearch

 

在Rails Migration中加上索引的話,用add_index語法,例如: add_index :events, :date 

⚠️ :加索引會在寫入數據時變慢,也會增長儲存空間,但查詢時會變快。 


在安裝gul的時候提示使用homebrew cask.居然要輸入密碼,我沒理解。通過google,這個應該是homebrew的擴展,能夠一句命令就能下載appstore以外的一些軟件,密碼多是用戶登錄密碼,我輸入appstore的密碼不成功提示❌。而後9次之後自動從git上下載。但速度及其慢,失敗後,重新再來一次,輸入用戶名密碼迅速下載成功!✅。 

 brew cask list  //能夠看到下載的列表。

 


 


SQL語法是否區分大小寫?

關鍵字不區分大小寫(select, from, where等)。通常表名和列名區分大小寫,最好統一用小寫。 



 數據庫規範化 Normalization (點擊進維基百科)

 數據庫設計的一系列原理和技術,目的是減小數據冗餘,增進數據的一致性。節省空間,增長修改數據時的效率,避免數據不一致的錯誤。

一階規範化: 不能有重複組,不能少了惟一識別碼。

1.不要用不少字段來表達同一個事實設計column的時候,不要有目的徹底同樣的列 ,喜歡的食物1,喜歡的食物2

2.每條記錄應有一個id,這是防止徹底相同的記錄(如兩筆徹底同樣的交易記錄)。

3.每一個字段的值都只能是單一值(不能一個字段,有多個有意義的值並用逗號隔開)。

 

二階規範化:移除重複語意的row

就是拆分表。

1.要求數據表裏的全部數據都和該數據表的鍵(主鍵和候選鍵)有徹底依賴關係。

2.若是有哪些數據只和一個鍵的一部分有關的話,就得把它們獨立出來變成另外一個數據表。

 Rails 是創建多對多關係。增長一個relationship的表格儲存關鍵id.

 

三階規範化:要求全部非鍵屬性都只和候選鍵有相關性,也就是說非鍵屬性之間應該是獨立無關的。

。。。 

 

數據庫設計實務

 用model的關係來思考。

http://www.vivekmchawla.com/erd-crows-foot-relationship-symbols-cheat-sheet/

這個圖定義了一對一,一對多,多對多關係等圖表。 Compound
 

Primary Key 主鍵:

不null,不重複。Rails只支持單一id,不支持組合key.

種類:

1.自動遞增的id.Rails 默認方式;

2.UUID (點擊看維基百科)Universally Unique Identifier

  •  分佈式系統喜歡用 
  •  或是看成 token URL 功能
3.  Natural key (例如身分證號碼, ISBN, 國碼 ISO ALPHA-2) 等等,不過你須要真的確認不會重複。

 

加primary key 的 SQL:

CREATE TABLE events (id INTEGER NOT NULL PRIMARY KEY, name TEXT, ...);

加auto increment primary key的 SQL(各家語法不同,如下是SQLite3)

CREATE TABLE events(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT,...); 

//Rails自動產生遞增的id.

 

Foreign Key (Reference Key)外鍵: 

 

 外鍵字段一般以_id結尾。在Rails中,寫belongs_to的Model,就是foreign key 字段的那個model。

在Rails Migration中能夠用add_foreign_key語法,數據庫會提供驗證。

不過在Rails中偏好在應用層解決數據的正確性。 例如dependent屬性來處理刪除狀況。  

class Event < ApplicationRecord
has_many :registrations, :dependent => :destroy
end

 

  • :destroy 把依賴的registrations也一併刪除,並執行Registration的destroy回叫。
  • :delete  如destroy但不執行回叫。
  • :nullify  這是默認值,不會幫忙刪除registrations, 但會把registrations的外部鍵event_id設爲NULL。
  • :restrict_with_exception 限定,若是有任何依賴的registrations資料,則連event都不能刪除。執行刪除時會報告❌,ActiveRecord::DeleteRestrictionError
  • :restrict_with_error不容許刪除。執行刪除時會回傳false,在@event.errors中會留下❌信心。

 

 

逆規範化 denormalized

 數據庫規範化並非徹底的真理,在不一樣場景下甚至會作逆規範化的設計。如olap用作分析用途。

 

另外,在一些須要局部效能最佳化的場景,也會作一些逆規範化的設計,例如 Rails 的 計數快取 Counter Cache功能,將數量額外用一個字段先存下來,免去以後計算的查詢時間。這也是一種逆規範化的設計。


 


下載graphviz,時候出現❌。 

 >brew install graphviz

... 

/usr/local/Homebrew/Library/Homebrew/brew.rb:12:in `<main>': Homebrew must be run under Ruby 2.3! You're running 2.0.0. (RuntimeError) 

 

我複製粘貼到google:找到一個相關的已解決問題帖 https://github.com/Homebrew/brew/issues/3299

解決辦法:

1. Ran brew update and retried you prior step? 若是不行。

2. Ran brew doctor, fixed all issues and retried your prior step? 若是不行

3. Ran brew config and brew doctor 。


 個人辦法,第二遍使用 brew install graphviz,而後出現下載,但下載部分出現error.

在 brew update後,再次brew install graphviz,出現一次error,但brew list 中有graphviz.

我在jdstore3/jdstore中安裝Rails-erd ,並bundle install成功,而後執行rake erd成功,創建了erd.pdf。

相關文章
相關標籤/搜索