分類
Database

選擇適合的資料庫-Choosing The Right Database

這篇文章很棒, 仔細地介紹了資料庫的種類與特性, 給在選擇應用資料庫的朋友們, 有個較為完整的概念與取捨:

https://towardsdatascience.com/choosing-the-right-database-c45cd3a28f77

簡單整理一下重點:

CAP: https://zh.wikipedia.org/wiki/CAP%E5%AE%9A%E7%90%86

在分散式的系統架構下, 不能同時滿足這三個條件的 CAP定理:

  1. Consistency: 一致性, 所有分散的節點都能有一致的資料
  2. Availability: 可用性, 每次查詢皆可取得正確(但不一定最新)的結果.
  3. Partition tolerance: 分區容錯性, 部分節點異常或資料異常, 系統仍能保持運作.

(也請參考這篇: https://ithelp.ithome.com.tw/articles/10158554)

而傳統資料庫管統系統需要能滿足 ACID 的部分如下:

https://zh.wikipedia.org/wiki/ACID

  1. Atomicity: 原子性, 在一個交易內的異動是不會被分割的.
  2. Consistency: 一致性.
  3. Isolation: 獨立性, 在各交易操作的狀況下, 是不會互相影響的.
  4. Durability: 持續性, 在未異動的資料, 是能持續保持不變的.

傳統 ACID 在現代資料庫是無法同時滿足的, 所以在分散架構下的 CAP 是另一個檢視要件, 主要應用在 NoSQL 環境.

另外各式資料庫的特性如同原文介紹, 有 key-value, document, graph 不同的資料存放型態.

而其中最重要的部分是應用情境的問題:

  • How many relationships are in your data?
  • What is the level of complexity in your data?
  • How often do the data change?
  • How often does your application query the data?
  • How often does your application query the relationship underlying the data?
  • How often do your users update the data?
  • How often do your users update the logic in the data?
  • How critical is your Application in a disaster scenario?

若是能妥善理解與處理這些可能的問題, 就能找到適合的資料庫, 而實務上也是有可能互相混搭應用的, 區分為不同的資料庫應用方式, 但更重要的是適當的搭配與選擇.

繼續閱讀:
https://blog.longwin.com.tw/2013/03/nosql-db-choose-cap-theorem-2013/

分類
Database

SQLite線上玩-sqliteonline

這個網站提供了線上執行 SQLite 的功能, 對於初學者, 或想要了解 SQL 語法的人有很大的幫助.

https://sqliteonline.com

除了可以學習 SQLite 功能外, 其實在一般的應用, 有時想要快速的建立幾個簡單的 table 與輸入一些資料後存出來, 使用這個網站也能很快速容易地達成, 舉例來說, 建立一個 table:

CREATE TABLE t_product (f_id INTEGER PRIMARY KEY, f_name VARCHAR, f_cat VARCHAR, f_desc VARCHAR)

輸入一些資料:

INSERT INTO t_product VALUES (1, ‘哈利波特’, ‘書’, ‘有趣的魔法故事書’),
(2, ‘波西傑克森’, ‘書’, ‘半神半人的希臘混血人故事’),
(3, ‘充電線’, ‘3c’, ‘usb 充電線’),
(4, ‘iphone x’, ‘3c’, ‘apple最新手機’)

進行查詢:

select * from t_product WHERE f_cat = ‘3c’

select f_cat, Count(*) from t_product group by f_cat

而且可以方便地使用 link 分享, 上面的結果連結為:

https://sqliteonline.com/#fiddle-5aa25641295bd9gdjejr1mc0

另外也可以下載對應的 SQLite 資料檔, 真是太方便了呢.

若是希望使用應用程式來讀取, 可以使用 DB Browser for SQLite 這個軟體:

http://sqlitebrowser.org/

同時有 Windows 與 MAC 的版本可供使用.

[2020/8/11]
繼續學習更多: https://www.guru99.com/sqlite-tutorial.html

分類
Database

MongoDB的管理工具-Robo 3T

無論是使用 mlab 的 mongdb 線上資料庫, 或是自建的 mongodb 環境, 都需要一個方便的操作管理工具, 可以使用這個好用的 robomongo 的 Robo 3T 工具, 官方連結:

https://robomongo.org/

它是一個 open source 的工具, 用來存取 mongodb, github 連結:

https://github.com/Studio3T/robomongo

同時有 Windows (install, portable), Mac, Linux 三種版本可供使用, 十分方便, 介面操作也很直覺容易, 是在使用 mongodb 的好用工具.

分類
Database

SQL Fiddle好用線上資料庫語法測試工具

線上的前端有好用的 jsfiddle (https://jsfiddle.net/), CodePen (http://codepen.io/), 今天發現了一個很棒的資料庫語法測試工具, SQL Fiddle, 網址如下:

http://sqlfiddle.com/

這個好用的工具分為左右兩側, 分別是 DDL,DML 與 SQL 兩塊, 左側的 DDL, DML 可以直接定義資料表與資料內容, 當然, 還是用標準的資料庫語法. 右邊則是於 DDL, DML 執行之後, 才能使用的 SQL 語法查詢與測試用.

這樣不僅能快速定義資料表供應用外, 最重要的是可以測試 SQL 的查詢語法. 從左上角 Menu 可以看到支援的資料庫有:

MySQL 5.6
MySQL 5.5
Oracle 11g R2
PostgreSQL 9.3
SQLite (WebSQL)
SQLite (SQL.js)
MS SQL Server 2014
MS SQL Server 2008

8種不同資料庫與版本, 十分方便. 另外於 DDL/DML的部分, 也可以直接用上方 Text To DDL 進行設定, 更加方便, 讓不會使用 DDL/DML 的人員, 也能無痛建立資料表, 例如:

table name: t_staff,
data:
name, age, title
Mary, 25, manager
Charlie, 18, Clerk
Fiona, 19, Clerk

(第一列為欄位名, 之後為資料)

就會生出以下語法:

接下來, 就可以在右側進行查詢, 如:

select * from t_staff where age > 20

就可以查出對應的資料了, 十分方便, 尤其對於要查找資料時的不同資料庫語法間的應用, 都有很大的幫助. 另外已完成的結果, 還能快速分享, 對於查找問題, 有更多可以協同作業的可能, 上面的範例如下:

http://sqlfiddle.com/#!9/18a360/1

分類
Database

MS SQL Server將可在Linux環境下執行了

這篇文章: http://blogs.microsoft.com/blog/2016/03/07/announcing-sql-server-on-linux/ 提到了, 即將在 linux 上執行 SQL Server 了.

這個微軟的當家資料庫服務器, 終於跨出了微軟的作業系統了, 有用過的應該都說好, 但到了 linux 下又是另一番風貌, 姑且不論效能如何, 微軟能走出這一步, 真的很值得肯定. 當然相信也能大幅拓展這個在微軟作業系統以外的其他平台市場, 讓 SQL Server 的優點發揮出來.

還蠻期待的.

繼續閱讀:
http://www.bnext.com.tw/article/view/id/38871

分類
Database

Mysql dump檔案分割(大文字檔案分割指令-csplit)

在要還原 mysql 備份檔時, 有時整個 database 的 backup file 檔案很大, 要找出其中某一個區塊很花時間, 也需要用一個能打開大檔的文字編輯器才能找到, 有沒有更方便的方法, 找出其中某個 table 呢? 可以使用好用的文字檔分割工具 csplit (linux 指令)

舉例來說, 我們要找一個 table t_table1 的 dump 檔案內容, 而備份的 mysql database 檔案為 mysqlbackup.sql 我們使用指令如下:

csplit -f output_file mysqlbackup.sql "/Table structure for table `t_table1`/" "/Table structure for table/"

這樣一共會輸出三個檔案: output_file00, output_file01, output_file02, 其中的 output_file01 就會是我們要的 t_table1 這個資料表的 dump 資料了. 當然, 前後的檔案就分別是切出 01 後的 00, 02 了.

所以工作原理就是將 Table structure for table `t_table1` 與 Table structure for table 兩個分割點來進行檔案切割. 所以若是希望把所有的 table 檔分出來, 則可以使用以下指令:

csplit -f output_file mysqlbackup.sql "/Table structure for table/" "{10}"

其中的 10 就是要重覆做幾次(包含前面做第一次, 後面再做10次共11次), 重點是若有 11 個 table, 應該就可以分出 11 個檔案, 其中的 00 沒有用, 而 01~11 就會是那 11個 table 的 dump file, 所以若是不知 table 數量時, 後面的那個參數, 就不能寫超過總數的次數, 否則會一個檔案也不輸出.

另外可以使用 {*} 的方式如下:

csplit -f output_file mysqlbackup.sql "/Table structure for table/" "{*}"

會直接盡可能地使用重覆到無法使用, 也就是 table 有多少就會做多少次, 下面 PS 有說明我在 FreeBSD 8.2 執行時有錯誤, 不過在 CentOS 是可以正常執行的.

使用 csplit 可以快速的切割超級大檔案, 把要找的資料整理出來, 很方便又實用.

繼續閱讀:
http://www.computerhope.com/unix/ucsplit.htm

PS. 雖然上面這篇介紹有使用 {*} 來重覆作業, 不過我實際執行時, 會發生:
csplit: *}: bad repetition count 的錯誤訊息, 環境是 FreeBSD 8.2, 不過在另一台 CentOS 7.1 是可以正常執行的, 所以若是不能使用 {*} 請參考上面說明.

分類
Database

MySQL資料表不存在的資料就新增-存在就忽略(或異動)的語法

在新增資料於資料表時, 有個需求, 是不存在的資料就新增, 存在的資料就不動作(或是要處理一些異動), 這樣的需求如何操作呢?

可以使用 INSERT IGNORE INTO [table] ….. 的語法,

若是要異動則使用

INSERT INTO [table]….. ON DUPLICATE KEY UPDATE col=expr …..

可以參考以下語法:
http://cain19811028.blogspot.tw/2015/01/mysql-insert-ignore-replace-on.html
https://mariadb.com/kb/en/mariadb/insert-on-duplicate-key-update/

分類
Database

Mysql的字串轉型問題

Mysql 在字串欄位比對上, 有個奇妙的狀況. 當然, 在正常一般狀況下不太容易發生.

某欄位 f1 為 varchar 或 char , 而在 where 條件下, 使用了

where f1=’sometext’

這樣沒有問題.

但若是使用了

where f1=0

會發生什麼事呢? 結果是全部成立.

根據 f1=0 來看, mysql 會先將 f1 欄位轉為數字, 而將字串轉為數字, 在 mysql 中, 會是 0 的結果, 導致會全部成立. 檢查以下語法:

SELECT cast( 'test string' AS SIGNED )

結果會是 0 , 也就解開了這個問題.

另外可以參考一下 cast 的語法:
http://dev.mysql.com/doc/refman/5.6/en/cast-functions.html

其 case ( data as type ) 中的 type, 可以為以下幾種:
BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL[(M[,D])]
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]

供各位在不小心, 使用了等於零在判斷條件時, 發生問題的參考.

分類
Database

SQL Server資料表使用GUID欄位考量

在資料表中, 使用 GUID做為clustered index時, 很容易因為是隨機產生的值, 而導致資料存放的離散, 可以利用這個函數來改善:

NEWSEQUENTIALID()

該函數是循序地建立 GUID, 也是唯一值, 但可以降低離散的狀況, 進而改善未能有效填滿及離散的問題.

當然, 若是 GUID欄位沒有使用在 cludtered index時, 則比較不需要擔心這個問題.

參考資料:
http://technet.microsoft.com/zh-tw/library/ms189786.aspx

分類
Database

SQL Join語法圖示

這篇主要目的是介紹集合, 使用 SQL Join 指令時的語法與集合的關係, 資料可以參考這篇: http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins

(以上圖片引用自: http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins )

在資料庫查詢時, 使用 Join 語法是用來查詢多個資料表間的相關資料狀況用的, 區分為 inner join 及 outer join 兩種, 不指定時預設為 inner join, 也就是在兩邊都存在的資料, 使用 inner join 查詢, 例如 select a.sid from table_a a inner join table_b b on a.sid=b.sid 時, 會出現同時在 a 與 b 的 sid 都存在的資料.

例如 table_a 存在 1, 2, 3, 5, 6, 7, 10, 11 共八筆資料, 而 table_b 存在 2, 3, 4, 5, 6, 7, 8 共七筆資料時, 使用 inner join 則取出 2, 3, 5, 6, 7 共五筆資料.

而 left join (也就是 left outer join), 則是取出以左邊為主, 不管右邊是否存在的資料, (不存在的資料會用 null 值補齊欄位), 如:

select a.sid from table_a a left join table_b b on a.sid=b.sid

則會取出 1, 2, 3, 4, 5, 7, 10 , 11 共八筆資料,

而 right join (也就是 right outer join), 則是取出以右邊為主, 不管左邊是否存在的資料, 如:

select a.sid from table_a a right join table_b b on a.sid=b.sid

則會取出 2, 3, 4, 5, 6, 7, 8 共七筆資料.

另外還有 full join (也就是 full outer join)則是兩邊都取出來, 如:

select a.sid, b.sid from table_a a full join table_b b on a.sid=b.sid

則會取出兩個表全部的內容, 1, 2, 3, 5, 6, 7, 10, 11, 4, 8 共十筆資料,

其他若是需要做其他的集合, 只需要再加上 where 中的 is null 就可以產生差集這樣的方式.

繼續閱讀:
http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins
http://blog.wu-boy.com/2009/01/mysqlleft-right-inner-outer-join-%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95/