in บันทึก

My GNOME Shell Extensions – Part 1

สำหรับ Linux User ที่เลือก GNOME (อ่านว่า กะโนม) เป็น desktop environment ซึ่งปัจจุบัน (ตุลาคม 2561) เวอร์ชั่นล่าสุดคือ GNOME 3.30 กรณีที่อยากลองใช้ ณ ตอนนี้ก็มี Ubuntu 18.10 Cosmic Cuttlefish ซึ่งจะออกใกล้ ๆ นี้มาให้ทดลองใช้งาน

สำหรับดิสโทรอื่น หลัก ๆ ก็ยังใช้เวอร์ชั่น 3.28 กันอยู่ สามารถตรวจสอบเวอร์ชั่นในเครื่องตัวเองได้จากคำสั่งนี้ (เครื่องตัวเองตอนนี้ใช้เวอร์ชั่น GNOME Shell 3.28.3)

gnome-shell --version

ใครที่อยากลอง GNOME Shell 3.30 ก็ใช้กำลังภายในกันนิดนึงแต่ส่วนตัวก็ยังแนะนำให้ใช้เวอร์ชั่นเดิม ๆ นั่นแหล่ะปลอดภัยสุดแล้ว

GNOME Shell เดิม ๆ นั้นก็ไม่ถึงกับง่อยหรอก แต่ถ้าอยากให้ชีวิตง่ายขึ้น GNOME Shell Extensions ช่วยได้ ซึ่งก็มีให้เลือกใช้งานกันตามแต่ละปัญหาของแต่ละคน (ส่วนใหญ่ปัญหาการใช้งานก็ไม่ค่อยต่างกันมากนัก  :P)

ส่วนตัวแล้วเลือกใช้ Extensions อยู่ไม่กี่ตัว มาดูกันว่ามีตัวไหนกันบ้าง (แนะนำให้ติดตั้ง sudo apt install gnome-tweak-tool ด้วย) เรียงลำดับตามตัวอักษรหล่ะกันครับ

  1. Applications Menu by fmuellner
    Add a category-based menu
    สำหรับเรียกเมนูโดยจัดกลุ่มแอพปลิชั่นให้ คล้ายปุ่ม Start ในฝั่ง Windows นั่นแหล่ะ
  2. Blyr by yozoon
    Apply a Blur Effect to GNOME Shell UI elements

    ช่วยเพิ่ม Effect  Blur ใน Background เมื่อเรียกหน้าจอ Activities Overview Screen ขึ้นมา มันดู Sexy ขึ้นนะ
  3. Caffeine by eon
    Disable the screensaver and auto suspend

    ปิดการทำงานของ Screensaver
  4. Clipboard Indicator by Tudmotu
    Clipboard Manager extension for Gnome-Shell – Adds a clipboard indicator to the top panel, and caches clipboard history.

    เพิ่มความสามารถของ Clipboard เราสามารถกำหนดประวัติการใช้งาน Clipboard ได้ (Default อยู่ที่ 30 รายการ)
  5. Coverflow Alt-Tab by p91paul
    Replacement of Alt-Tab, iterates through windows in a cover-flow manner.

    โดยปกติเมื่อเรากดคีย์ Alt-Tab/Alt-Shift-Tab จะเป็นการเลื่อน (Switch) ไปยังแอพปลิเคชั่นที่เปิดอยู่ Extensions นี้ช่วยปรับให้ลักษณะการเลื่อนเป็นแบบ Coverflow ตัวอย่าง
  6. cpufreq by konkor
    Gnome CPU Frequency Monitor and Governor Manager.

    สามารถกำหนด Profile ให้ CPU ทำงานได้ โดยปกติ Linux เองก็ฉลาดมากพอที่จะกำหนดความเร็วของ CPU ตามลักษณะการใช้งาน แต่บางครั้งเราก็อยากรีดความเร็วณ ตอนนั้น หรือลดความเร็วลงเพื่อประหยัดพลังงาน Extension ตัวนี้ช่วยได้
  7. Dash to Dock by michele_g
    A dock for the Gnome Shell. This extension moves the dash out of the overview transforming it in a dock for an easier launching of applications and a faster switching between windows and desktops. Side and bottom placement options are available.

    Dock ที่ติดมากับ Ubuntu ถึงแม้จะ Fork Dash to Dock มาแต่ก็ปรับแต่ง/ทำอะไรไม่ได้มาก ถ้าพฤติกรรมการใช้งานเรา แค่นั้นไม่พอก็ติดตั้ง Dash to Dock ช่วย (Dock จะเก่งขึ้นมากถึงมากที่สุด)
  8. Dash to Panel by jderose9
    An icon taskbar for the Gnome Shell. This extension moves the dash into the gnome main panel so that the application launchers and system tray are combined into a single panel, similar to that found in KDE Plasma and Windows 7+. A separate dock is no longer needed for easy access to running and favorited applications.
    อยากได้ Dock ฟิล Windows ก็ใช้ตัวนี้ (เราก็ใช้สลับกับ Dash to Dock นะ)
  9. Disconnect Wifi by kgshank
    Adds a Disconnect option for Wifi in status menu, when a network is connected. Shows a Reconnect option, after network is disconnected.

    เพิ่มเมนู Disconnect หลังจากที่เชื่อมต่อ Wifi แล้ว เป็น Extension เหมือนไม่มีอะไรแต่มีประโยชน์มาก
  10. EasyScreenCast
    This extension simplifies the use of the video recording function integrated in gnome shell, allows quickly to change the various settings of the desktop recording.

    Screen recording ติดมากับ GNOME Shell แต่การใช้งานก็ไม่ได้ง่ายนัก สำหรับใครที่อยากใช้และไม่ต้องการ Extension ตัวนี้ วิธีใช้ พอไปอ่านแล้วคุณจะกลับมาติดตั้ง Extensions ตัวนี้ 😛
  11. Freon by UshakovVasilii
    Shows CPU temperature, disk temperature, video card temperature (NVIDIA/Catalyst/Bumblebee&NVIDIA), voltage and fan RPM (forked from xtranophilist/gnome-shell-extension-sensors)

    แสดงอุณหภูมิทั้ง CPU และ Video Card รองรับทั้งทั้งฝั่งเขียวและแดงนะครับ
  12. Frippery Move Clock by rmyorston
    Move clock to left of status menu button

    ย้ายตำแหน่งของนาฬิกาเฉย ๆ
  13. gTile by scherepanov
    Tile windows on a grid.

    ช่วยให้การจัดหน้าต่างที่กำลังเปิดอยู่ทั้งหมดดูง่ายและเป็นระเบียบ ไม่ต้องลากเองนี่จัดตำแหน่งให้เลย
  14. Impatience by gfxmonk
    Speed up the gnome-shell animation speed
    รู้สึกว่าเครื่องมีการตอบสนองมันช้าใช่ไหม เครื่องช้าไหม แต่เปล่าเลย Animation ล้วน ๆ งั้นเรามาเร่ง Speed Animation กัน คือถ้าไม่ชอบก็สามารถปิดได้ ใช้ Gnome Tweak Tool > Appearance แต่ Animation ก็อยากใช้แต่เร่งความเร็วนิดนึง ก็ติดตั้งเลยครับ

จบ Part 1 นะครับ ^_^ (เหลืออีกประมาณ 10 กว่าตัว)

Set video wallpaper for your Ubuntu 18.04 Bionic Beaver

การมาของ Live Wallpaper ทำให้ความจำเจเราหายไปบ้าง แต่ก็นั่นหล่ะ เราอยากได้แบบนี้บ้างใน Linux ที่ใช้งานอยู่ (ปัจจุบันใช้ Ubuntu 18.04 Bionic Beaver) พบว่ามีทูลหลายตัวที่ช่วยทำเรื่องเกี่ยวกับ Wallpaper ไม่ว่าจะเป็น Package หรือ Extension สำหรับ Gnome Shell

หรือแม้แต่ komorebi เอง

และก็มี Tool อีกตัวหนึ่งซึ่งสามารถทำได้เหมือนกันคือ VLC Media Player โดยปกติเราใช้ VLC เป็น Media Player หลักอยู่แล้วเลยไม่ต้องติดตั้งอะไรเพิ่มเติมแต่ถ้ายังไม่ได้ติดตั้งก็ติดตั้งได้เลยตามนี้

sudo snap install vlc
หรือ
sudo apt install vlc

ต่อมาก็ใช้ VLC แบบ Command Line กำหนดให้เล่นวิดีโอใน Mode Wallpaper อ่านรายละเอียดคำสั่ง/Options ได้จากที่นี่ รูปแบบคำสั่งก็ใช้แค่นี้แหล่ะ

cvlc --video-wallpaper --no-audio --loop --no-video-title-show "Video File Path"

หรือเปิด VLC ในโหมด GUI ปกติแล้วกำหนดให้เป็น Wallpaper โดยการกด Hot Keys ‘w’


ผลลัพธ์ที่ได้ก็ตามนี้

ป.ล.

Split comma separated string to multiple rows

สำหรับใครที่เคยใช้ฟังก์ชั่น GROUP_CONCAT() ใน  MySQL มาก่อนก็พอจะเดาผลลัพธ์จากฟังก์ชั่นนี้ได้ว่า ผลลัพธ์จะเป็นค่าตามคอลัมภ์ที่ถูกกรุ๊ป (GROUP BY) และนำมาต่อกันด้วยเครื่องหมายที่ระบุ ปกติค่าดีฟอลต์จะเป็น comma ‘,’ รูปแบบคำสั่งก็จะประมาณนี้

GROUP_CONCAT([DISTINCT] expr [,expr ...]
             [ORDER BY {unsigned_integer | col_name | expr}
                 [ASC | DESC] [,col_name ...]]
             [SEPARATOR str_val])

ตัวอย่าง


**ภาพจาก mysqltutorial

ข้างบนนี่คือต้นเหตุ มักจะมีกรณีที่เราได้ผลลัพธ์มาแล้ว นั่นคือ “A,B,C” และเราต้องการแยกข้อความที่ได้มาออกเป็นแต่ละแถว (ตาราง t ก่อนที่จะผ่านฟังก์ชั่น GROUP_CONCAT() นั่นแหล่ะ) ดูตัวอย่างกัน

CREATE TABLE DEMO (
    ID INTEGER PRIMARY KEY AUTO_INCREMENT,
    PID VARCHAR(20) NOT NULL,
    ICD10LIST VARCHAR(255) DEFAULT NULL
);
 
INSERT INTO DEMO(ID, PID, ICD10LIST) VALUES(NULL, '101', 'E119,E112,I10'), (NULL, '102', 'E119,E112'), (NULL, '103', 'E119,I10');

ข้อมูลในตารางเป็นแบบนี้ (คุ้น ๆ กันไหม 5555)

**แนวคิดของคำสั่งก็คือทำการสร้างตารางค่า Index ที่อยู่ในชุด/เซตข้อความเพื่อแยกแต่ละไอเท็มออกมา

SELECT
  DEMO.ID,
  DEMO.PID,
  SUBSTRING_INDEX(SUBSTRING_INDEX(DEMO.ICD10LIST, ',', numbers.n), ',', -1) AS ICD10
FROM
  (SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5) numbers INNER JOIN DEMO
  ON CHAR_LENGTH(DEMO.ICD10LIST)-CHAR_LENGTH(REPLACE(DEMO.ICD10LIST, ',', '')) >= numbers.n-1
ORDER BY
  PID, n

ผลลัพธ์ที่ได้

จบปิ๊ง !!!

ป.ล.

  • ตาราง numbers จะสร้างไว้ก่อนก็ได้ ปกติก็ใช้บ่อย ๆ นะครับจะด้วย RECURSIVE CTE ก็ได้หรือตัวนี้
  • ตัว Split String จะทำเป็นฟังก์ชั่นไว้ก็ได้นะ ^_^
  • ข้อมูลเป็นข้อมูลสมมุติจาก Data Exchange สมมุติแห่งหนึ่ง

 

 

Simulate keyboard input and mouse activity and more on Raspberry Pi

นานมาแล้ว (หรือช่วงนี้ก็มี 555) มีโปรแกรมกลุ่มพวกคลิกโฆษณาอัตโนมัติ ได้รับความนิยมอย่างล้นหลาม ใคร ๆ ก็ทำงานบนอินเตอร์เนตกัน จนมีประโยคสุดฮิตสแปมมาอยู่เนือง ๆ

โดยหลัก ๆ ละโปรแกรมเหล่านี้ก็จะจำลองการทำงานของเมาส์และคีย์บอร์ดแหล่ะ และวันนึงก็ได้ใช้ ด้วยความที่ตัว Raspberry Pi ที่ใช้งานอยู่จำเป็นต้องจำลองการเลื่อน/คลิกเมาส์และใช้คีย์บอร์ดขึ้นมา xdotool ช่วยคุณได้ เริ่มติดตั้งกันเลย

sudo apt-get install xdotool

ตัวอย่างการใช้งานก็ง่าย ๆ สร้างสคริปท์ขึ้นมา อาจจะทำงานผ่าน Crontab ก็ได้ เช่น ต้องการ
Resize all visible gnome-terminal windows

#!/bin/bash

WIDS=`xdotool search --onlyvisible --name "gnome-terminal"`
for id in $WIDS; do
  xdotool windowsize $id 500 500
done

# As of version 2.20100623, you can do this simpler version of above:
xdotool search --onlyvisible --classname "gnome-terminal" windowsize %@ 500 500

จบปิ๊ง   !!

ป.ล.
อยากใช้ก็มีให้ใช้ได้ทันที แบบนี้สิดี
Github : https://github.com/jordansissel/xdotool

Yaru Gtk Themes Available in Dark and Light Variants for Ubuntu 18.04

Yaru-light and Yaru-dark based on ‘Yaru theme (Ubuntu community theme)’ https://github.com/ubuntu/yaru powered by the community on the Ubuntu hub. Yaru theme design for GTK 3, GTK 2 and Gnome-Shell. Some of the additional tweaks:

  • Switch gtk control with round radius.
  • Transparent gnome-shell.

Installation :

  1. Just unzip the file and place it in your themes directory i.e. ~/.themes/or /usr/share/themes/
  2. Install gnome-tweak-tool
    sudo apt install gnome-tweak-tool
  3. Select the theme as ‘Yaru-light’ or ‘Yaru-dark’

Download : https://www.gnome-look.org/p/1252100/
Base : https://github.com/ubuntu/yaru

sysctl – changing kernel parameters at runtime

#
# /etc/sysctl.conf - Configuration file for setting system variables
# See /etc/sysctl.d/ for additional system variables.
# See sysctl.conf (5) for information.
#

#kernel.domainname = example.com

# Uncomment the following to stop low-level messages on console
#kernel.printk = 3 4 1 3

##############################################################3
# Functions previously found in netbase
#

# Uncomment the next two lines to enable Spoof protection (reverse-path filter)
# Turn on Source Address Verification in all interfaces to
# prevent some spoofing attacks
#net.ipv4.conf.default.rp_filter=1
#net.ipv4.conf.all.rp_filter=1

# Uncomment the next line to enable TCP/IP SYN cookies
# See http://lwn.net/Articles/277146/
# Note: This may impact IPv6 TCP sessions too
#net.ipv4.tcp_syncookies=1

# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1

# Uncomment the next line to enable packet forwarding for IPv6
#  Enabling this option disables Stateless Address Autoconfiguration
#  based on Router Advertisements for this host
#net.ipv6.conf.all.forwarding=1


###################################################################
# Additional settings - these settings can improve the network
# security of the host and prevent against some network attacks
# including spoofing attacks and man in the middle attacks through
# redirection. Some network environments, however, require that these
# settings are disabled so review and enable them as needed.
#
# Do not accept ICMP redirects (prevent MITM attacks)
#net.ipv4.conf.all.accept_redirects = 0
#net.ipv6.conf.all.accept_redirects = 0
# _or_
# Accept ICMP redirects only for gateways listed in our default
# gateway list (enabled by default)
# net.ipv4.conf.all.secure_redirects = 1
#
# Do not send ICMP redirects (we are not a router)
#net.ipv4.conf.all.send_redirects = 0
#
# Do not accept IP source route packets (we are not a router)
#net.ipv4.conf.all.accept_source_route = 0
#net.ipv6.conf.all.accept_source_route = 0
#
# Log Martian Packets
#net.ipv4.conf.all.log_martians = 1
#

###################################################################
# Magic system request Key
# 0=disable, 1=enable all
# Debian kernels have this set to 0 (disable the key)
# See https://www.kernel.org/doc/Documentation/sysrq.txt
# for what other values do
#kernel.sysrq=1

###################################################################
# Protected links
#
# Protects against creating or following links under certain conditions
# Debian kernels have both set to 1 (restricted) 
# See https://www.kernel.org/doc/Documentation/sysctl/fs.txt
#fs.protected_hardlinks=0
#fs.protected_symlinks=0

###################################################################
# Improving performance
# Virtual memory
# Consensus is that setting vm.dirty_ratio to 10% of RAM is a sane value if RAM is say 1 GB (so 10% is 100 MB). But if the machine has much more RAM, say 16 GB (10% is 1.6 # GB), the percentage may be out of proportion as it becomes several seconds of writeback on spinning disks. A more sane value in this case may be 3 (3% of 16 GB is #approximately 491 MB).

vm.swappiness=10
vm.dirty_ratio=10
vm.dirty_background_ratio=5
vm.vfs_cache_pressure=50
vm.dirty_background_bytes=4194304
vm.dirty_bytes=4194304

# Networking
# Increasing the size of the receive queue.
net.core.netdev_max_backlog=100000
net.core.netdev_budget=50000
net.core.netdev_budget_usecs=5000
#
# Increase the maximum connections default 128
net.core.somaxconn=1024
#
# Increase the memory dedicated to the network interfaces
net.core.rmem_default=1048576
net.core.rmem_max=16777216
net.core.wmem_default=1048576
net.core.wmem_max=16777216
net.core.optmem_max=65536
net.ipv4.tcp_rmem=4096 1048576 2097152
net.ipv4.tcp_wmem=4096 65536 16777216
#
# increase the default 4096 UDP limits
net.ipv4.udp_rmem_min=8192
net.ipv4.udp_wmem_min=8192
#
# Enable TCP Fast Open
net.ipv4.tcp_fastopen=3
#
# Tweak the pending connection handling
net.ipv4.tcp_max_syn_backlog=30000
net.ipv4.tcp_max_tw_buckets=2000000
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=10
net.ipv4.tcp_slow_start_after_idle=0
#
# Change TCP keepalive parameters
net.ipv4.tcp_keepalive_time=60
net.ipv4.tcp_keepalive_intvl=10
net.ipv4.tcp_keepalive_probes=6
#
# Enable MTU probing
net.ipv4.tcp_mtu_probing=1
#
# TCP Timestamps
net.ipv4.tcp_timestamps=0
#
# TCP/IP stack hardening
# TCP SYN cookie protection
net.ipv4.tcp_syncookies=1
#
# TCP rfc1337
net.ipv4.tcp_rfc1337=1
#
# Reverse path filtering
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.all.rp_filter=1
#
# Log martian packets
net.ipv4.conf.default.log_martians=1
net.ipv4.conf.all.log_martians=1
#
# Disable ICMP redirecting
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.default.accept_redirects=0
#
# disable ICMP redirect sending when on a non router
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
#
# Enable Ignoring to ICMP Request
net.ipv4.icmp_echo_ignore_all=1

 
Source : https://wiki.archlinux.org/index.php/Sysctl

transfer.sh – Easy file sharing from the command line

transfer.sh เป็นบริการ file sharing แบบต้องใช้ command line ตอนนี้ก็รองรับทั้งการฝากไฟล์ที่อยู่ในเครื่อง (local file) s3 (Amazon S3) และ gdrive (Google Drive) โดยฟีเจอร์หลัก ๆ ก็มี

  • ผ่าน shell command ได้ (Powershell ด้วย)
  • ขนาดไฟล์สูงสุดได้ 10 GB
  • ฝากไฟล์ได้ 14 วัน
  • เข้ารหัสไฟล์ได้
  • กำหนดเงื่อนไข (จำนวน) การดาวน์โหลด
  • ฟรี 👏👏👏

ตัวอย่างแบบเบสิคเลย

# Uploading is easy using curl
$ curl --upload-file ./hello.txt https://transfer.sh/hello.txt
https://transfer.sh/66nb8/hello.txt

$ curl -H "Max-Downloads: 1" -H "Max-Days: 5" --upload-file ./hello.txt https://transfer.sh/hello.txt
https://transfer.sh/66nb8/hello.txt
# Download the file
$ curl https://transfer.sh/66nb8/hello.txt -o hello.txt

หรือจะเป็นการ Backup MySQL ก็ทำได้เหมือนกัน

# Backup, encrypt and transfer
$ mysqldump --all-databases|gzip|gpg -ac -o-|curl -X PUT --upload-file "-" https://transfer.sh/test.txt

* ถ้าใครสนใจลองเข้าไปใช้งานได้ที่เว็บ transfer.sh ส่วนตัวแล้วเป็นบริการที่ชอบเลย ด้วยความที่เป็นอะไรที่ใช้งานง่ายและมีประโยชน์จริง ๆ

** โปรเจคอยู่บน github (https://github.com/dutchcoders/transfer.sh) จะเอามาทำใช้เองก็ได้มี Docker ให้ด้วย

สร้าง docker container สำหรับทำ REST API กัน – Full fake data

ในวันที่ต้อง Mock API แบบด่วน ๆ สำหรับทดสอบ Front-end (แต่ Back-end จริง ๆ มันยังอยู่แค่ในร่างออกแบบ) งั้นก็เริ่มกันเลย

เราใช้ json-server เป็นตัวช่วยทำ Mock API ซึ่งก็ตอบโจทย์และเร็วสุดละ สิ่งที่เราต้องทำเพิ่มคือสร้างชุดข้อมูลสำหรับทดสอบเท่านั้นเอง

npm install -g json-server

ส่วนการสร้างชุดข้อมูลก็ใช้ faker.js (เราใช้ lodash เพิ่ม ก็ติดตั้งเข้าไปพร้อมกันเลย)

npm install faker lodash

สร้างชุดข้อมูลแบบ random ด้วยไฟล์ชื่อ generator.js เข้าไป

// generator.js
module.exports = function () {
    var faker = require("faker");
    var _ = require("lodash");
    return {
        customers: _.times(Math.floor((Math.random() * 1000) + 1), function (n) {
            return {
                id: n+1,
                firstname: faker.name.firstName(),
                lastname: faker.name.lastName(),
                birthdate: faker.date.past(50, new Date("Sat Sep 20 1992 21:35:02 GMT+0700 (ICT)")),
                address: faker.address.streetAddress(),
                city: faker.address.city(),
                country: faker.address.country(),
                email: faker.internet.email(),
                avatar: faker.internet.avatar()
            }
        })
    }
}

หลังจากที่เรา Start Server ด้วยคำสั่ง json-server generator.js ข้อมูลที่เรา generate ขึ้นหน้าตาก็ประมาณนี้

ท้ายสุดเราก็แพ็คลง Container เลย โดยสร้าง Dockerfile ไว้ใช้งานยาว ๆ  (เป็นลางว่า Back-end จะยังไม่เสร็จในเร็ววันใช่ไหม 55555)

FROM node:10-alpine

LABEL author="mf"
LABEL version="latest"

ENV NPM_CONFIG_LOGLEVEL info
ENV TZ Asia/Bangkok

RUN apk add --no-cache tzdata \
    && cp /usr/share/zoneinfo/Asia/Bangkok /etc/localtime \
    && echo "Asia/Bangkok" >  /etc/timezone \
    && rm -rf /var/cache/apk/*

# Create application directory
RUN mkdir -p /data \
    && npm install -g json-server lodash faker
WORKDIR /data

VOLUME [ "/data" ]
EXPOSE 3000

# Default command
ENTRYPOINT ["json-server"]
CMD ["--help"]

หลังจาก build Dockerfile แล้วก็ลองรันกันเลย ถ้าไม่ทำอะไรผิดพลาดผลลัพธ์มันก็ควรจะเป็นดังรูป

docker run -d -p 3000:3000 -v `pwd`/app:/data mf/mockup-api --watch generator.js --host 0.0.0.0

จบปิ๊งง ^_^

#ยังคิดถึงเสมอ

กะละมังอาบน้ำของมังกี้ยังวางอยู่หน้าบ้านเหมือนเดิม
สายจูง ลูกบอลอีกลูกก็ยังอยู่ในลังของเล่นอยู่
บางครั้งก็มีขนเธอปลิวมาบ้าง ถึงแม้เราจะทำความสะอาดบ้านครั้งใหญ่ไปหลายรอบละ
ต้นมะลิที่ปลูกไว้หลังบ้าน ตรงที่เธอนอนอยู่… ต้นที่เป็นของเธอก็ยังรอดปลอดภัย
ผ่านมาปีนึงละ ก็ยังคิดถึงเธอเสมอ

 

 

Hierarchical and recursive queries in MySQL

Hierarchical query คืออะไร ?

A hierarchical query is a type of SQL query that handles hierarchical model data. They are special cases of more general recursive fixpoint queries, which compute transitive closures.

อยากบอก(บ่น) ว่าก่อนที่ MySQL 8 จะออกนี่การดึงข้อมูลแบบลำดับชั้นลักษณะต้นไม้ (Tree) แบบนี้โคตรเปลืองพลังงาน แต่ตอนนี้ดีขึ้นมาก ต้องขอบคุณจริง ๆ ที่ MySQL อิมพลีเมนต์ Common Table Expression (CTE) ให้ใช้ได้ซะที เขียนคำสั่งสั้นลง ประสิทธิภาพดีขึ้น (ก็แหงสิเจ้าของเค้าทำออกมาเอง)

ยกตัวอย่างข้อมูลลักษณะแบบลำดับชั้น เช่น โครงสร้างองค์กร เธรดในคอมเมนต์ต่าง ๆ ข้อมูล Categories and sub-categories ที่เห็นภาพชัด ๆ  เลยคือ โครงสร้างองค์กร (Organization charts ) นี่ง่ายสุดละ มีหัวหน้าเป็นรูทและมีลูกน้องในความดูแลและบางทีลูกน้องก็มีเบ้ต่อลงไปอีกที ลักษณะข้อมูลแบบรูปนี้เลย


ว่าแล้วก็ติดตั้ง MySQL 8 สำหรับใช้งานกัน

docker run -d -p 3306:3306 --name mysqltest --restart always -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=demo mysql:8

โดยธรรมเนียมปฏิบัติทั่วไป ของตารางที่เก็บข้อมูลในลักษณะนี้ก็จะออกแบบคล้าย ๆ แบบนี้ โดยให้คอลัมภ์ parent เก็บข้อมูลหัวหน้า

DROP TABLE IF EXISTS category;
CREATE TABLE IF NOT EXISTS category(
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(20) NOT NULL,
        parent INT DEFAULT NULL
);

INSERT INTO category VALUES
(1,'Root A', NULL),
(2,'Item 1', 1),
(3,'Item 2', 1),
(4,'Item 3', 3),
(5,'Root B', NULL),
(6,'Item 4', 5),
(7,'Item 5', 6),
(8,'Root C', NULL),
(9,'Item 6', 8);

การดึงข้อมูลในลักษณะ Recursive MySQL ได้เตรียมคำสั่งให้แล้ว รูปแบบการใช้งาน

with_clause:
    WITH [RECURSIVE]
        cte_name [(col_name [, col_name] ...)] AS (subquery)
        [, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...

ลักษณะของคำสั่งนี้คือ


*ภาพจาก mysqltutorial : A Definitive Guide To MySQL Recursive CTE

เรามาดูผลลัพธ์กัน

WITH RECURSIVE categorypath(id, name, dept, breadcrumbs) AS
(
  SELECT id, name, 0, CAST(name AS CHAR(1000))
  FROM category 
  WHERE parent IS NULL
  UNION ALL
  SELECT c.id, c.name, cp.dept + 1, CONCAT_WS('/', cp.breadcrumbs, c.name) 
  FROM categorypath cp 
    JOIN category c ON cp.id = c.parent
)
SELECT * FROM categorypath ORDER BY breadcrumbs;

ไปอ่านเพิ่มเติมกันได้ที่

  • https://mysqlserverteam.com/mysql-8-0-labs-recursive-common-table-expressions-in-mysql-ctes/
  • https://www.percona.com/live/17/sites/default/files/slides/Recursive%20Query%20Throwdown.pdf
  • https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL

จบปิ๊ง ^__^
ป.ล.1 วันหยุด วันฝนตกฉันควรนอนกกใครสักคนอยู่ใต้ผ้าห่มนี่นา
ป.ล.2 เศร้าาาวันทำงาน