Ray's IT Blog

Ubi Libertas Ibi Patria


  • Home

  • About

  • Tags

  • Categories

  • Archives

What is PassthroughSubject & CurrentValueSubject

Posted on 2023-01-18

I think we can make analogies with real world cases.

PassthroughSubject = A doorbell push button
// for button action

When someone rings the door, you are notified only if you are at home (you are the subscriber)

PassthroughSubject doesn’t have a state, it emits whatever it receives to its subscribers.

CurrentValueSubject = A light switch Someone turns on the lights in your home when you are outside. You get back home and you know someone has turned them on.
// for slider or tabbar

CurrentValueSubject has an initial state, it retains the data you put in as its state.

Reference

https://stackoverflow.com/questions/60482737/what-is-passthroughsubject-currentvaluesubject
https://www.youtube.com/watch?v=n9r3pHypWjk&ab_channel=iCode

MySQL index mechanism

Posted on 2022-05-21

Introduction

alt text

When data is stored on disk-based storage devices, it is stored as blocks of data. These blocks are accessed in their entirety, making them the atomic disk access operation. Disk blocks are structured in much the same way as linked lists; both contain a section for data, a pointer to the location of the next node (or block), and both need not be stored contiguously.

Due to the fact that a number of records can only be sorted on one field, we can state that searching on a field that isn’t sorted requires a Linear Search which requires (N+1)/2 block accesses (on average), where N is the number of blocks that the table spans. If that field is a non-key field (i.e. doesn’t contain unique entries) then the entire tablespace must be searched at N block accesses.

Whereas with a sorted field, a Binary Search may be used, which has log2 N block accesses. Also since the data is sorted given a non-key field, the rest of the table doesn’t need to be searched for duplicate values, once a higher value is found. Thus the performance increase is substantial.

What is indexing?

Indexing is a way of sorting a number of records on multiple fields. Creating an index on a field in a table creates another data structure which holds the field value, and a pointer to the record it relates to. This index structure is then sorted, allowing Binary Searches to be performed on it.

The downside to indexing is that these indices require additional space on the disk since the indices are stored together in a table using the MyISAM engine, this file can quickly reach the size limits of the underlying file system if many fields within the same table are indexed.

How does it work?

Firstly, let’s outline a sample database table schema;

Field name Data type Size on disk
id (Primary key) Unsigned INT 4 bytes
firstName Char(50) 50 bytes
lastName Char(50) 50 bytes
emailAddress Char(100) 100 bytes

Note: char was used in place of varchar to allow for an accurate size on disk value. This sample database contains five million rows and is unindexed. The performance of several queries will now be analyzed. These are a query using the id (a sorted key field) and one using the firstName (a non-key unsorted field).

Example 1 - sorted vs unsorted fields

Given our sample database of r = 5,000,000 records of a fixed size giving a record length of R = 204 bytes and they are stored in a table using the MyISAM engine which is using the default block size B = 1,024 bytes. The blocking factor of the table would be bfr = (B/R) = 1024/204 = 5 records per disk block. The total number of blocks required to hold the table is N = (r/bfr) = 5000000/5 = 1,000,000 blocks.

A linear search on the id field would require an average of N/2 = 500,000 block accesses to find a value, given that the id field is a key field. But since the id field is also sorted, a binary search can be conducted requiring an average of log2 1000000 = 19.93 = 20 block accesses. Instantly we can see this is a drastic improvement.

Now the firstName field is neither sorted nor a key field, so a binary search is impossible, nor are the values unique, and thus the table will require searching to the end for an exact N = 1,000,000 block accesses. It is this situation that indexing aims to correct.

Given that an index record contains only the indexed field and a pointer to the original record, it stands to reason that it will be smaller than the multi-field record that it points to. So the index itself requires fewer disk blocks than the original table, which therefore requires fewer block accesses to iterate through. The schema for an index on the firstName field is outlined below;

Field name Data type Size on disk
firstName Char(50) 50 bytes
(record pointer) Special 4 bytes

Note: Pointers in MySQL are 2, 3, 4 or 5 bytes in length depending on the size of the table.

Example 2 - indexing

Given our sample database of r = 5,000,000 records with an index record length of R = 54 bytes and using the default block size B = 1,024 bytes. The blocking factor of the index would be bfr = (B/R) = 1024/54 = 18 records per disk block. The total number of blocks required to hold the index is N = (r/bfr) = 5000000/18 = 277,778 blocks.

Now a search using the firstName field can utilize the index to increase performance. This allows for a binary search of the index with an average of log2 277778 = 18.08 = 19 block accesses. To find the address of the actual record, which requires a further block access to read, bringing the total to 19 + 1 = 20 block accesses, a far cry from the 1,000,000 block accesses required to find a firstName match in the non-indexed table.

Reference

https://stackoverflow.com/questions/1108/how-does-database-indexing-work

https://dataschool.com/sql-optimization/how-indexing-works/
https://www.mdpi.com/2079-9292/9/9/1348/htm

B+-tree B-tree M-way search

Posted on 2022-05-19

Introduction

The MySQL index structure is based on the B+-tree, which is an extension of the B-tree. The B-tree itself is a type of M-way search tree.

Body

M-way search

An M-way tree is a rooted tree in which each node has no more than m children. A binary tree is a special case where m = 2, and a ternary tree is another case with m = 3, limiting its children to three.

alt text

B-tree

B-tree is an M-way search tree with two special properties:

  1. It is perfectly balanced: every leaf node is at the same depth.
    (With a balanced tree, access1 is O(log n).
    With an unbalanced tree, access1 is O(n) (worst case).)

alt text

  1. Every node, except perhaps the root, is at least half-full, i.e. contains M/2 or more values (of course, it cannot contain more than M-1 values). The root may have any number of values (1 to M-1).

B+-tree

Difference Between B-Tree And B+ Tree

| B-tree | B+-tree |
| ——- | — | —– |
| Data is stored in leaf nodes as well as internal nodes. | Data is stored only in leaf nodes. |
| Leaf nodes cannot be linked together. | Leaf nodes are linked together to form a linked list.|
| Searching is a bit slower as data is stored in internal as well as leaf nodes. | Searching is faster as the data is stored only in the leaf nodes. |
| Deletion operation is complex. | Deletion operation is easy as data can be directly deleted from the leaf nodes. |
| No redundant search keys are present. | Redundant search keys may be present. |

alt text

Searching is faster as the data is stored only in the leaf nodes.

B+ trees don’t have data associated with interior nodes, more keys can fit on a page of memory. Therefore, it will require fewer cache misses in order to access data that is on a leaf node.

The leaf nodes of B+ trees are linked, so doing a full scan of all objects in a tree requires just one linear pass through all the leaf nodes. A B tree, on the other hand, would require a traversal of every level in the tree. This full-tree traversal will likely involve more cache misses than the linear traversal of B+ leaves.

B-tree Deletion operation is complex.

Data is stored in leaf nodes as well as internal nodes, so there are two different situations we need to deal with, and B+-tree only stores data in leaf nodes.

No redundant search keys are present.

B-tree only includes < > equal is not an option.

Reference

https://www.youtube.com/watch?v=aZjYr87r1b8&ab_channel=AbdulBari
https://www.youtube.com/watch?v=C_q5ccN84C8&ab_channel=FullstackAcademy

https://www.softwaretestinghelp.com/b-tree-data-structure-cpp/
https://webdocs.cs.ualberta.ca/~holte/T26/b-trees.html

https://stackoverflow.com/questions/59206128/balanced-vs-unbalanced-binary-tree-clarification-needed
https://stackoverflow.com/questions/870218/what-are-the-differences-between-b-trees-and-b-trees

https://en.wikipedia.org/wiki/M-ary_tree

Git Example

Posted on 2019-05-12

開篇

簡單的示範一下使用Git 的例子

例子將模擬二個2位員工的分工和合併

2位員工將會在各自的branch 加入新的file 和同時更改一個共用的file

就如日常中二個人合作寫project的情況

例子將用.swift 的文件示範

不要使用 apple rich text 會出現merge 的問題

正文

首先開一個folder

在里面加入一個config.swift

然後在config.swift寫入

1
let SettingCommon = "Common"

再打開terminal cd 到folder 的位置 輸入

1
git init

成功會出現

1
Initialized empty Git repository in folder 的位置

然後繼續在terminal 輸入

1
2
git add .
git commit -m "git init"

成功會出現

1
2
3
[master (root-commit) 9ed71be] git init
1 file changed, 8 insertions(+)
create mode 100644 config.swift

然後開二個branch 模擬二人合作的情況 在terminal 輸入

1
2
git branch user1
git branch user2

切換到user1 branch 模擬user 1 工作 在terminal 輸入

1
git checkout user1

成功會出現

1
Switched to branch 'user1'

然後在config.swift加入一行

1
2
let SettingCommon = "Common"
let SettingOne = "one" <-- 加入的一行

加入一個func1.swift

在func1.swift寫入

1
let func1 = "func1"

然後在terminal 輸入

1
2
git add .
git commit -m "user1 init"

再切換到user2 branch 模擬user 2 工作 在terminal 輸入

1
git checkout user2

成功會出現

1
Switched to branch 'user2'

然後在config.swift加入一行

1
2
let SettingCommon = "Common"
let SettingTwo = "two" <-- 加入的一行

加入一個func2.swift

在func2.swift寫入

1
let func2 = "func2"

然後在terminal 輸入

1
2
git add .
git commit -m "user2 init"

回到master branch 準備merge
在terminal 輸入

1
git checkout master

成功會出現

1
Switched to branch 'master'

在terminal 輸入

1
git merge user1

成功會出現

1
2
3
4
5
6
Updating 9ed71be..8df35f6
Fast-forward
config.swift | 1 +
func1.swift | 8 ++++++++
2 files changed, 9 insertions(+)
create mode 100644 func1.swift

再merge user2在terminal 輸入

1
git merge user2

成功會出現

1
2
3
Auto-merging config.swift
CONFLICT (content): Merge conflict in config.swift
Automatic merge failed; fix conflicts and then commit the result.

打開config.swift 會看見

1
2
3
4
5
6
let SettingCommon = "Common"
<<<<<<< HEAD
let SettingOne = "one"
=======
let SettingTwo = "two"
>>>>>>> user2

把以下的三行刪掉

1
2
3
<<<<<<< HEAD
=======
>>>>>>> user2

文件將變成

1
2
3
let SettingCommon = "Common"
let SettingOne = "one"
let SettingTwo = "two"

回到terminal 輸入

1
2
git add .
git commit -m "merge two func"

成功會出現

1
[master 119ec7e] merge two func

完成 灑花

結尾

下篇 Git 將在 Xcode 的 project 中示範使用 Git

*唠騷* *棄我去者 昨日之日不可留 亂我心者 今日之日多煩憂 四方八面各式各樣的煩悶揮之不去 身體健康出現問題 西醫看不好 中藥飲不少 略有好轉 只能說革命尚未成功 同志仍需努力 *

SQL_2

Posted on 2019-04-07

alt text

Functional Dependency

Prime attribute -> non-Prime attribute

Partial Dependency

Part of Prime attribute -> non-Prime attribute

Transitive Dependency

non-Prime attribute -> non-Prime attribute

remove in BCNF

non-Prime attribute -> Prime attribute

1NF

  1. Eliminate repeating groups in table ( 消滅多重記錄 每一個Cell 只有一組資料 )
  2. Identify each set of related data with a primary key (每一條資料都需要獨一無二的主鍵)

Trading Table

Customer Name Date Number
Mr. Chan Monday 19.00, -28.00
Mr. Wong Wed -80.00, -80.00
Mr. Lee Friday 100.00, -40.00, 150
  1. after 1NF.1
    Trading Table
Customer Name Date Number
Mr. Chan Monday 19.00
Mr. Chan Monday -28.00
Mr. Wong Wed -80.00
Mr. Wong Wed -80.00
Mr. Lee Friday 100.00
Mr. Lee Friday -40.00
Mr. Lee Friday 150
  1. after 1NF.2
    Trading Table
primary key Customer Name Date Number
1 Mr. Chan Monday 19.00
2 Mr. Chan Monday -28.00
3 Mr. Wong Wed -80.00
4 Mr. Wong Wed -80.00
5 Mr. Lee Friday 100.00
6 Mr. Lee Friday -40.00
7 Mr. Lee Friday 150

2NF

  1. be in firsts normal form (1NF) (符合1NF)
  2. All attributes (Non-key Columns) dependent on the key (所有資料都是完全功能相依於主鍵 資料需直接相關於主鍵)

Price Table

Item ID (primary key) Price Supplier ID Supplier Name Supplier Address
100 59 1 A Supplier SA A
102 20 1 A Supplier SA A
100 69 2 B Supplier SA B
  1. after 2NF.2

Price Table

Item ID (primary key) Supplier ID Price
100 1 59
102 1 20
100 2 69

Supplier Table

Supplier ID (primary key) Supplier Name Supplier Address
1 A Supplier SA A
2 B Supplier SA B

3NF

  1. the entity is in second normal form (2NF) (符合2NF)
  2. no non-prime attribute is transitively dependent of any key ( 如果 AB 可以求得C AB -> C , C 就不應該出現)

EX1

Order Table

Order ID Customer Name Unit Price Quantity Total
100 David 35 3 105
101 Jim 25 2 50
102 Bob 25 3 75

Total可由 Unit Price + Quantity 求得 (Unit Price + Quantity ) -> Total
所以刪除 Total

Order ID Customer Name Unit Price Quantity
100 David 35 3
101 Jim 25 2
102 Bob 25 3

EX2

Price Table

Item ID Price Supplier ID Supplier Name Supplier Address
100 59 1 A Supplier SA A
102 20 1 A Supplier SA A
100 69 2 B Supplier SA B

Supplier Address 可由 Supplier ID 求得 Supplier ID -> Supplier Address
所以刪除 Supplier Address 結果如上2NF 例子

BCNF / 3.5 NF

  1. It should be in 3re Normal Form
  2. For any dependency A -> B, A should be a super key

College Enrollment Table

student_id subject professor
101 Java P.Java
101 C++ P.Cpp
102 Java P.Java.2
103 C# P.Chash
104 Java P.Java

Candidate Key
(student_id, subject) -> professor
(non-prime attribute) professor -> subject (prime attribute)
professor can find subject but professor not super key NOT IN BCNF

p_id professor subject
201 P.Java Java
202 P.Cpp C++
203 P.Java.2 Java
204 P.Chash C#
student_id p_id
101 P.Java
101 P.Cpp
102 P.Java_2
103 P.Chash
104 P.Java

https://www.youtube.com/watch?v=NNjUhvvwOrk

https://zh.wikipedia.org/wiki/第一正規化
https://en.wikipedia.org/wiki/First_normal_form

http://epaper.gotop.com.tw/pdf/AED000900.pdf
http://www.gotop.com.tw/epaper/e0815/AED000900.pdf

http://faculty.stust.edu.tw/~jehuang/oracle/ch3/3-1.htm

http://cc.cust.edu.tw/~ccchen/doc/db_04.pdf

https://www.youtube.com/watch?v=UrYLYV7WSHM&t=935s

SQL_1

Posted on 2019-04-06

開篇

在之前的Git 文章曾說過 Git 是現在程式員必學的技能之一

今天要說的就是另一個幾乎必學的語言 SQL

一般程式員都最少會一種主要的程式語言 + Git + SQL

就像是坦補DD 一樣的鐵三角

SQL 是一種控制relational database 的語言

而relational database 是常用的儲存資料方法

而SQL 有不少分支像 MySQL Oracle SQL MsSQL 等等之類

但儲存資料前需要不少的準備工作

其中之一就是設計DB 的架構

而 Normalization 是必不可少的環節

結尾

下篇SQL 將寫SQL Normalization 1NF 2NF 3NF 3.5NF 的筆記

iOS Building GUI

Posted on 2019-03-26

正文

XYWH

開一個iOS 的 project
然後在default的VC中的viewdidload中加入

1
2
3
4
5
6
7
8
9
10
11
12
13
import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let XYWDView = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
XYWDView.backgroundColor = .red
self.view.addSubview(XYWDView)
}

}

alt text

Storyboard + Autolayout

alt text

alt text

XIB + Autolayout

首先在AppDelegate didFinishLaunchingWithOptions 中加入

1
2
3
4
5
6
7
8
9
10
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window?.backgroundColor = UIColor.white
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = UINavigationController(rootViewController: ViewController())

return true
}

然後在刪去 Main Interface 中的Main SB

加入一個Xib

加入Class ViewController

把 Outlet View 連上

最後加入 NSLayoutConstraint

alt text

alt text

alt text

alt text

alt text

Pure Code + Autolayout

首先跟上面一樣在AppDelegate didFinishLaunchingWithOptions 中加入一段Code

然後在刪去 Main Interface 中的Main SB

最後在default的VC中的viewdidload中加入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = .white

let colorView = UIView()
colorView.backgroundColor = .red
colorView.translatesAutoresizingMaskIntoConstraints = false

self.view.addSubview(colorView)

self.view.addConstraint(NSLayoutConstraint(item: colorView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100))
self.view.addConstraint(NSLayoutConstraint(item: colorView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100))
self.view.addConstraint(NSLayoutConstraint(item: colorView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 100))
self.view.addConstraint(NSLayoutConstraint(item: colorView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 100))
}

alt text

Git 常用功能簡介

Posted on 2019-03-19

正文

基本功能

no. function name output
1 git init Init 當下目錄成Git 項目
2 git clone 第一次 下載一個Git 項目至本地
3 git pull 取回遠程倉庫修改至本地倉庫并合并至工作區
4 git add 添加當下目錄文件之修改至暫存區
5 git commit 提交暫存區修改至本地倉庫
6 git push 推代碼至遠程倉庫
7 git diff 顯示暫存區和工作區的差別
8 git checkout [someBranch] 切換到指定分支
9 get fetch 下載遠程倉庫到當下倉庫 但未至工作區
10 git merge 合并指定分支至當下分支
11 git branch [someBranch] 開一個新的分支
12 git log 檢視提交的歷史記錄
13 git reflog 檢視提交改變的所有歷史記錄
13 git reset [target] 切換至指定歷史記錄

附上一張Git 工作流程圖 增加對以上功能的了解

alt text

Branch

Branch 可以說是Git 的殺手鐧

因為Git 開分支並不用把整個Project都Copy一次

而只是記錄變化 令Git 開分支的速度和開支比其他VCS要低很多

開分支和切換的方法在上面的表格就有了

結尾

正在想下一篇到底寫繼續iOS or SQL

iOS UI build in SB XIB PureCode Texture(ASDK) WEEX

Posted on 2019-02-23

開篇

第二篇Blog 將會寫我最愛的iOS

從最基本的建立GUI 開始

正文

XYWH

在沒有Autolayout 的年代

每個iOS都是用 X-position Y-position Width Height 建立起來的

現在除了少數情況外 大部分的情況都不會再用了

Storyboard + Autolayout

大概是最多人使用的方法

因為最易入門

XIB + Autolayout

在SB 出現前比較多人使用的方法

現在也有不少人使用 因為在View 重用上比SB 簡單

而且又比純碼多了一些可觀性

Pure Code + Autolayout

比較在乎View 重用和在Git 解決衝突比較簡單的方法

Other

像是Texture (ASDK) WEEX 之類的Framework

詳細使用方法可請教Google 大神

基本上是少了一些功能 增加了速度的方案

結尾

下篇iOS 將用Code示範如何使用2.2-2.4三種方法

Git 歷史與簡介

Posted on 2019-02-21

開篇

Git 可以說是現在任何語言程式員必修的內功心法

不論是一個人開發應用程式,或一群人團隊合作開發,少了VCS必然事倍功半

因為是一套任何程序員都必需,而且在可見將來都是必需的工具

所以決定第一篇Blog決定寫 Git 的簡單介紹

Git 相關文會分開多篇貼出 深入淺出 從歷史介紹到實際使用上的體驗 方便個人閱讀

Git 歷史

在Git 出現前比較有名的VCS有 CVS 和 SVN

SVN 基本上是一個集中式VCS

基本上就是只有一個倉庫一套Source Code

每一個人要更新都必需要先連上唯一的倉庫

好處是方便管理 壞處是沒備份 需要額外增加備份

而Git 則同時有一個統一網上倉庫也有Local 個人的倉庫

CVS 則有像不能改名之類的問題 和只支授文字檔

但兩者後來都被Git 的 Branch 功能幹掉

結尾

第一篇Blog 小試牛刀 就寫到這裹

下篇Git 的文章將介紹一下Git 的殺手級功能 Branch

和Git 的一些基本功能

10 posts
5 tags
© 2024 Ray yu
Powered by Hexo
|
Theme — NexT.Pisces v5.1.4