Category: Database

  • Oracle MySQL Cluster :- The shared-nothing architecture (Manual Installation)

    1. สิ่งที่ต้องเตรียม ได้แก่ Ubuntu Server 16.04 (รุ่น x86_64 architecture) จำนวนอย่างน้อย 4 เครื่อง (แต่ควรอย่างน้อย 6 เครื่อง), IP Address 4 IP, Software MySQL Cluster โหลดที่ https://edelivery.oracle.com/ (ต้องสมัครสมาชิกให้เรียบร้อยก่อน) ใช้คำค้นว่า MySQL Cluster (จะมีรุ่น 7.5.5 ให้โหลด) โดยไฟล์ที่ใช้งานชื่อว่า V840854-01.zip MySQL Cluster 7.5.5 TAR for Generic Linux (glibc2.5) x86 (64bit)

    2. 4 เครื่องประกอบด้วยอะไรบ้าง
      2 x data nodes เปลี่ยน IP ให้ตรงกับที่ใช้งาน
      192.168.106.32  Data-node1
      192.168.106.33  Data-node2
      1 x SQL/NoSQL Application Node
      192.168.106.42  SQL-Node
      1 x Management Node
      192.168.106.40  Management-node
    3. เริ่มที่ Management Node
      1. ssh 192.168.106.40 -l sudo_user (user ที่เรียกใช้คำสั่ง sudo ได้)
      2. คลายแฟ้ม V840854-01.zip ด้วยคำสั่ง
        unzip V840854-01.zip (อาจต้องติดตั้งเพิ่มเติมด้วยคำสั่ง sudo apt install unzip)
      3. จะได้แฟ้ม  mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz คลายแฟ้ม mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz ด้วยคำสั่ง
        tar zxvf mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz
      4. เปลี่่ยนชื่อ mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64 เป็น mysql
        mv mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64 mysql
      5. คัดลอกแฟ้ม mysql/bin/ndb_mgmd และ mysql/bin/ndb_mgm ไปไว้ที่ /usr/local/bin
        cp mysql/bin/ndb_mgm* /usr/local/bin/
      6. สร้างโฟลเดอร์ /var/lib/mysql-cluster และสร้างแฟ้ม /var/lib/mysql-cluster/config.ini
        sudo mkdir -p /var/lib/mysql-cluster/
      7. เพื่อเป็นการบอก Management node ว่า Data Node และ SQL Node มีใครบ้าง ให้สร้าง config.ini ไว้ที่ /var/lib/mysql-cluster ด้วยคำสั่ง
        cat<< EOF | sudo tee /var/lib/mysql-cluster/config.ini
        เพิ่มข้อความต่อไปนี้ลงไป
        [ndbd default]
        NoOfReplicas=2
        DataMemory=80M
        IndexMemory=18M
        [mysqld default]
        [ndb_mgmd default]
        [tcp default]
        # Cluster Control / Management node
        [ndb_mgmd]
        hostname=192.168.106.40# Data Node 1
        [ndbd]
        hostname=192.168.106.32
        DataDir= /var/lib/mysql-cluster# Data Node 2
        [ndbd]
        HostName=192.168.106.33
        DataDir=/var/lib/mysql-cluster# SQL Node
        [mysqld]
        hostname=192.168.106.42

        # If you to add new SQL Node
        [mysqld]

        EOF

      8. เพิ่มข้อความต่อไปนี้ในแฟ้ม /etc/rc.local
        /var/lib/mysql-cluster/config.ini --configdir=/var/lib/mysql-cluster/
        โดยเพิ่มให้อยู่บรรทัดก่อนคำว่า exit 0 ตัวอย่าง /etc/rc.local
        #!/bin/sh -e
        #
        # rc.local
        #
        # This script is executed at the end of each multiuser runlevel.
        # Make sure that the script will "exit 0" on success or any other
        # value on error.
        #
        # In order to enable or disable this script just change the execution
        # bits.
        #
        # By default this script does nothing.
        ndb_mgmd -f /var/lib/mysql-cluster/config.ini --configdir=/var/lib/mysql-cluster/
        exit 0
      9. สั่งคำสั่ง
        sudo ndb_mgmd -f /var/lib/mysql-cluster/config.ini --configdir=/var/lib/mysql-cluster/
        ต้องเห็นข้อความว่า MySQL Cluster Management Server mysql-5.7.17 ndb-7.5.5 แปลว่า management node ทำงานแล้ว
      10. สามารถตรวจสอบด้วยคำสั่งอื่นๆ
        netstat -plntu
        ได้ผลดังภาพ สังเกตุบรรทัดที่เขียนว่า tcp 0 0 0.0.0.0:1186 แปลว่า management node ทำงานแล้ว
      11. สามารถทำซ้ำได้อีกเครื่อง (ไม่จำกัด) แต่ในตัวอย่างนี้มีเพียงเครื่องเดียว
      12. ส่งแฟ้ม mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz ให้ SQL node
        cd
        scp mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz sudo_user@192.168.106.42
    4. ติดตั้ง SQL Node
      1. ssh 192.168.106.42 -l sudo_user (User ที่สามารถเรียกใช้คำสั่ง sudo ได้)
      2. ติดตั้ง Package ที่จำเป็น
        sudo apt install libaio1
      3. สร้าง user  และ group
        sudo groupadd mysql
        sudo useradd -g mysql mysql
      4. คลายแฟ้ม mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz ด้วยคำสั่ง
        tar zxvf mysql-cluster-advanced-7.5.5-เพิ่มข้อความต่อไปนี้ในแฟ้ม /etc/rc.local
        /var/lib/mysql-cluster/config.ini --configdir=/var/lib/mysql-cluster/
        โดยเพิ่มให้อยู่บรรทัดก่อนคำว่า exit 0 ตัวอย่าง /etc/rc.locallinux-glibc2.5-x86_64.tar.gz
      5. เปลี่่ยนชื่อ mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64 เป็น mysql
        mv mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64 mysql
      6. ย้าย mysql ไปที่ /usr/local/ ด้วยคำสั่ง
        sudo mv mysql /usr/local
      7. สร้างโฟลเดอร์และสั่งคำสั่งต่อไปนี้
        sudo mkdir /usr/local/mysql/data
        sudo mkdir /var/lib/mysql-files
        sudo chown mysql:mysql /var/lib/mysql-files
        sudo chown mysql:mysql /usr/local/mysql/data
      8. สร้างแฟ้ม /etc/my.cnf ด้วยคำสั่ง
        cat << EOF | sudo tee /etc/my.cnf
        เพิ่มข้อความต่อไปนี้ลงไป
        # MySQL Config
        [mysqld]
        datadir=/usr/local/mysql/data
        socket=/tmp/mysql.sock
        user=mysql# Run ndb storage engine
        ndbcluster
        # IP address management node
        ndb-connectstring=192.168.106.40[mysql_cluster]
        # IP address management node
        ndb-connectstring=192.168.106.40# MySQL Pid and Log
        [mysqld_safe]
        log-error=/var/log/mysqld.log
        pid-file=/var/run/mysqld/mysqld.pid
        EOF
      9. สั่งคำสั่งต่อไปนี้เพื่อเตรียมฐานข้อมูล ในขั้นตอนนี้จะมีการสร้าง passwd ของ root ให้ด้วยโดยอัตโนมัติ  *จดไว้ด้วย*
        sudo /usr/local/mysql/bin/mysqld --initialize --user=mysql --datadir=/usr/local/mysql/data
      10. เพื่อให้ตัวควบคุมฐานข้อมูลทำงานอัตโนมัติสั่งคำสั่งต่อไปนี้
        sudo cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
        sudo systemctl enable mysqld.service
        sudo systemctl start mysqld
      11. สามารถทำซ้ำได้อีกเครื่อง (ไม่จำกัด) แต่ในตัวอย่างนี้มี SQL Node เพียงเครื่องเดียว
      12. ส่งแฟ้ม mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz ให้ SQL node
        cd
        scp mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz sudo_user@192.168.106.32
    5. ติดตั้ง Data Node
      1. ssh sudo_user@192.168.106.32  (sudo_user คือ user ที่เรียกใช้คำสั่ง sudo ได้)
      2. สร้างแฟ้ม /etc/my.cnf ด้วยคำสั่ง
        cat << EOF | sudo tee /etc/my.cnf
        เพิ่มข้อความต่อไปนี้เข้าไป
        # MySQL Config
        [mysqld]
        datadir=/usr/local/mysql/data
        socket=/tmp/mysql.sock
        user=mysql# Run ndb storage engine
        ndbcluster
        # IP address management node
        ndb-connectstring=192.168.106.40[mysql_cluster]
        # IP address management node
        ndb-connectstring=192.168.106.40# MySQL Pid and Log
        [mysqld_safe]
        log-error=/var/log/mysqld.log
        pid-file=/var/run/mysqld/mysqld.pid
        EOF
      3. ติดตั้ง Package ที่จำเป็น
        sudo apt install libaio1
      4. สร้าง user  และ group
        sudo groupadd mysql
        sudo useradd -g mysql mysql
      5. คลายแฟ้ม mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz ด้วยคำสั่ง
        tar zxvf mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64.tar.gz
      6. เปลี่่ยนชื่อ mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64 เป็น mysql
        mv mysql-cluster-advanced-7.5.5-linux-glibc2.5-x86_64 mysql
      7. ย้าย mysql ไปที่ /usr/local/ ด้วยคำสั่ง
        sudo mv mysql /usr/local
      8. สร้างโฟลเดอร์และสั่งคำสั่งต่อไปนี้
        sudo mkdir /usr/local/mysql/data
        sudo mkdir /var/lib/mysql-files
        sudo mkdir /var/lib/mysql-cluster
        sudo chown mysql:mysql /var/lib/mysql-files
        sudo chown mysql:mysql /usr/local/mysql/data
      9. สั่ง start service ด้วยคำสั่ง
        sudo  /usr/local/mysql/bin/ndbd
      10. เพิ่มข้อความต่อไปนี้ในแฟ้ม /etc/rc.local
        /usr/local/mysql/bin/ndbd โดยเพิ่มให้อยู่บรรทัดก่อนคำว่า exit 0
        ตัวอย่าง /etc/rc.local
        #!/bin/sh -e
        #
        # rc.local
        #
        # This script is executed at the end of each multiuser runlevel.
        # Make sure that the script will "exit 0" on success or any other
        # value on error.
        #
        # In order to enable or disable this script just change the execution
        # bits.
        #
        # By default this script does nothing.
        /usr/local/mysql/bin/ndbd
        exit 0
      11. ทำซ้ำสำหรับ Data Node2 (ไม่จำกัด)
    6. ทดสอบ Cluster
      1. พิมพ์คำสั่ง
        sudo /usr/local/mysql/bin/ndb_mgm
        เมื่อได้ prompt พิมพ์คำว่า show ได้ผลดังภาพ
      2. แปลว่าทำงานถูกต้องแล้ว..
    7. เชื่อมต่อกับ SQL Node เพื่อเปลี่ยนรหัสผ่าน root
      1. ssh sudo_user@192.168.106.42  (sudo_user คือ user ที่เรียกใช้คำสั่ง sudo ได้)
      2. พิมพ์คำสั่งต่อไปนี้เพื่อสร้าง link ไปยัง mysql client
        sudo ln -s /usr/local/mysql/bin/mysql /usr/bin
      3. เรียกใช้งาน mysql
        mysql -u root -p
        ใส่ passwd ที่จดไว้ในข้อ 4 ข้อย่อย 9 แล้วเปลี่ยนใหม่ด้วยคำสั่ง
        ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘newPassw0rd’
    8. ทุกครั้งที่จะทำอะไรผ่าน mysql client ต้องติดต่อกับ SQL Node เท่านั้นซึ่งตามตัวอย่างนี้มีเพียงเครื่องเดียวจึงไม่มีการทำ replicate data ใดๆ ทั้งสิ้นจำเป็นต้องเพิ่ม SQL Node เข้าไปอีก
    9. จบ.. ขอให้สนุกครับ

    อ้างอิง

    https://www.howtoforge.com/tutorial/how-to-install-a-mysql-cluster-on-ubuntu-16-04/

    https://medium.com/@ophasnoname_44358/mysql-cluster-7-5-5-on-ubuntu-16-04-step-by-step-9132cf76d5b8

     

  • Cassandra #02 Scale-Out to Multi-nodes

    ต่อจาก Cassandra #01 เริ่มต้นใช้งาน

    ความสามารถที่สำคัญของ Cassandra คือสามารถทำการ Scale Out หรือขยายความสามารถของระบบได้โดยการเพิ่มเครื่องคอมพิวเตอร์ในระดับ Commodity Hardware [1] เข้าไปใน Cluster

    ในบทความนี้ จะแสดงวิธีการสร้าง Cassandra Cluster ที่ประกอบไปด้วย 3 Node ชื่อ cassandra01, cassandra02 และ cassandra03 โดยมีชื่อ Cluster ว่า PSUCluster และกำหนดให้ cassandra01 เป็น Seed Node (ทำหน้าที่เป็นผู้ประสานงานสำหรับ Node ใหม่ๆเข้าร่วม Cluster)

    ขั้นตอนการขยายระบบแบบ Scale Out ไปยังหลายๆ Node แต่ละ Node ทำดังนี้

    1. ติดตั้ง Cassandra ตามขั้นตอนใน Cassandra #01 เริ่มต้นใช้งาน
    2. แก้ไขไฟล์ /etc/cassandra/cassandra.yaml ดังนี้
      # กำหนดชื่อ Cluster ที่ต้องการ
      cluster_name: 'PSUCluster'
      
      # กำหนด Seed Node ซึ่งมีไว้ให้ node ใหม่ประกาศตัวเองเพื่อเข้าร่วม Cluster
      # ควรมีไม่เกิน 3 Node ต่อ Data Center
      # ในที่นี้ กำหนดไว้เพียงตัวเดียว 
      seed_provider:
       parameters:
       - seeds: "192.168.107.111"
      
      # กำหนด listen_address เป็นค่าว่าง
      listen_address:
      
      # กำหนด endpoint_snitch เป็น GossipingPropertyFileSnitch
      # เพื่อให้สามารถมี Cluster แบบข้าง Data Center ได้
      endpoint_snitch: GossipingPropertyFileSnitch
      
    3. ในการเริ่มใช้งานครั้งแรก ให้ลบข้อมูลใน /var/lib/cassandra/data/system ออกก่อน
      sudo rm -rf /var/lib/cassandra/data/system/*
    4. ในการใช้ Endpoint Snitch แบบ GossipingPropertyFileSnitch ต้องลบไฟล์ cassandra-topology.properties ออกไปก่อน
      sudo rm /etc/cassandra/cassandra-topology.properties
    5. จากนั้นก็ Start Cassandra Service
      sudo service cassandra restart

    วิธีดูสถานะของระบบ

    sudo watch nodetool status

    ในตอนแรกจะเป็นแบบนี้

    เมื่อ cassandra02 เข้ามา

    และเมื่อครบ 3 Node

    วิธี Debug ว่าเกิดอะไรขึ้น

    sudo tail -f /var/log/cassandra/debug.log

     

    Reference

    [1] http://docs.datastax.com/en/landing_page/doc/landing_page/planning/planningHardware.html

    [2] http://docs.datastax.com/en/cassandra/3.0/cassandra/architecture/archIntro.html

    [3] https://docs.datastax.com/en/cassandra/3.0/cassandra/initialize/initSingleDS.html

  • Cassandra #01 เริ่มต้นใช้งาน

    Cassandra เป็นระบบ Database ที่เหมาะสำหรับการ Scalability และให้ High Availability โดยไปลดประสิทธิภาพ มีความทนทานสูง (Fault Tolerance) โดยสามารถใช้งานเครื่องคอมพิวเตอร์ทั่วไปๆ (Commodity Hardware) หรือ ใช้งาน Cloud Infrastructure สำหรับงานที่มีความสำคัญได้ (Mission Critical) สามารถกระจายสำเนา (Replication) ข้าม Data Center ได้อีกด้วย [1][3]

    ในบทความนี้ จะแสดงการติดตั้งบน Ubuntu 16.04 เพียงเครื่องเดียวก่อน และให้เห็นวิธีการติดต่อตัวฐานข้อมูล การส่ง Query เบื้องต้น

    # echo "deb http://www.apache.org/dist/cassandra/debian 310x main" | sudo tee -a /etc/apt/sources.list.d/cassandra.sources.list
    # curl https://www.apache.org/dist/cassandra/KEYS | sudo apt-key add -
    # sudo apt-get update
    # sudo apt-get install cassandra

    ต่อไป วิธีการส่งคำสั่งไปยัง Cassandra จะใช้งานผ่าน cqlsh (Cassandra Query Language Shell)

    # cqlsh -C
    Connected to Test Cluster at 127.0.0.1:9042.
    [cqlsh 5.0.1 | Cassandra 3.10 | CQL spec 3.4.4 | Native protocol v4]
    Use HELP for help.
    cqlsh>

    ใน Cassandra จะเรียก Database ว่า Keyspace วิธีที่จะดูว่ามี Keyspace อะไรอยู่บ้าง ใช้คำสั่ง [2]

    cqlsh> DESCRIBE keyspaces;
    system_schema system_auth system system_distributed system_traces

    สั่งสร้าง Keyspace ชื่อ test ด้วยคำสั่งต่อไปนี้

    cqlsh> CREATE KEYSPACE test WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 3};

    เนื่องจาก Cassandra มีลักษณะพิเศษที่ไม่เหมือนกับ Database Servers อื่นๆ ก็คือเรื่องการ Replication ตั้งแต่เริ่มต้น ในคำสั่งข้างต้น จะบอกว่า ระบบจากสร้าง 3 สำเนา เป็นหลัก (จะกล่าวรายละเอียดในตอนต่อๆไป)

    ต่อไป สั่งสร้าง Table ชื่อ table1

    csqlsh> use test;
    cqlsh:test> create table table1 (
     ... id text primary key,
     ... age int,
     ... firstname text,
     ... lastname text
     ... );
    

    คำสั่งในการ Insert ข้อมูล

    cqlsh:test> INSERT INTO table1 (id, age, firstname, lastname) VALUES ( '000001', 10, 'John', 'Doe' );

    คำสั่งในการ Select ข้อมูล

    cqlsh:test> SELECT * FROM table1;
    
     id | age | firstname | lastname
    --------+-----+-----------+----------
     000001 | 10 | John | Doe
    
    (1 rows)

    คำสั่งในการ Update ข้อมูล

    cqlsh:test> UPDATE table1
     ... SET age = 20
     ... WHERE id = '000001'
     ... ;
    cqlsh:test> SELECT * FROM table1;
    
     id | age | firstname | lastname
    --------+-----+-----------+----------
     000001 | 20 | John | Doe
    
    (1 rows)

    คำสั่งในการ Delete ข้อมูล

    cqlsh:test> DELETE FROM table1
     ... WHERE id = '000001';
    cqlsh:test> SELECT * FROM table1;
    
     id | age | firstname | lastname
    ----+-----+-----------+----------
    
    (0 rows)

    จะเห็นได้ว่า รูปแบบการใช้คำสั่งแทบจะไม่แตกต่างกับภาษา SQL ใน RDBMS ทั่วไปเลย

    Reference:

    [1] http://cassandra.apache.org/

    [2] http://docs.datastax.com/en/cql/3.1/cql/cql_using/useStartingCqlshTOC.html

    [3] http://docs.datastax.com/en/cassandra/3.0/cassandra/cassandraAbout.html

     

  • Juju #07 – กระจายโหลดข้ามเครื่อง

    ที่ผ่านมา เป็นการติดตั้ง Juju ซึ่งเบื้องหลังคือ LXD Container แต่ทั้งหมดยังอยู่บนเครื่องเดียวกัน

    ภาพต่อไปนี้ เป็นการทดสอบความเร็วในการตอบสนองของ WordPress ซึ่งเป็น Post ที่มีภาพจำนวนมาก และมีขนาดในการ Download ทั้งหมด 5 MB ใช้เวลาประมาณ 1.24 วินาที

    เมื่อใช้ jMeter ระดมยิงด้วยความเร็ว 100 Connections ต่อ 1 วินาที ต่อเนื่อง 10 วินาที ได้ผลว่า เวลาเฉลี่ยคือ 2.478 วินาที

    ต่อมาลองเพิ่มจำนวน Container จาก 1 เครื่องไปเป็น 3 เครื่อง แต่ทำงานอยู่บน Physical Server เดียวกัน

    แล้วทดลองยิงแบบเดิม ได้ผลออกมาคือ ใช้เวลาเฉลี่ย 1.663 วินาที

    จากนั้น ทดสอบแยก Container ออกไป เป็น 3 Physical Servers

    ได้ผลออกมาว่า ใช้เวลาลดลงเหลือเพียง 1.056 วินาทีเท่านั้น

    สรุป การกระจายโหลดออกไปยังหลายๆ Physical Servers ทำให้สามารถรับโหลดจำนวนมากได้

    ในบทความต่อไปจะมาลงรายละเอียดในการ Setup กัน

     

    Reference:
    https://www.digitalocean.com/company/blog/horizontally-scaling-php-applications/
    https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-in-ubuntu-16-04
    http://php.net/manual/de/mysqlnd-ms.loadbalancing.php
    https://serversforhackers.com/video/php-fpm-configuration-the-listen-directive
    http://nginx.org/en/docs/http/request_processing.html
    http://stackoverflow.com/questions/5328844/nginx-load-balance-with-dedicated-php-fpm-server
    https://code.google.com/archive/p/sna/wikis/NginxWithPHPFPM.wiki
    http://nginx.org/en/docs/http/load_balancing.html
    – http://opensource.cc.psu.ac.th/KM-container

  • Removing duplicate records by using Oracle’s ROWID

    ถ้าคุณมีตารางข้อมูลอยู่ และรู้ว่ามีบางแถวที่มีข้อมูลซ้ำซ้อนกัน ทางไหนเป็นวิธีที่ดีที่จะสามารถหาและกำจัดแถวที่มีข้อมูลซ้ำนี้ออกไปจากตารางของฐานข้อมูล Oracle ?

     

    การหาแถวที่มีข้อมูลซ้ำซ้อน

    เราสามารถหาข้อมูลแถวที่มีข้อมูลซ้ำซ้อนกันได้โดยใช้คำสั่ง select ดังนี้

     

    select a,b,count(*)

    from test

    group by a,b

    having count(*) > 1;

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

    A          B   COUNT(*)

    ———- ———- ———-

    1          2        259

    2          2          5

     

    จากตัวอย่างในตาราง test นี้เราจะกำหนดว่าให้ค่าในคอลัมภ์ a และ b จะต้องมีค่าไม่ซ้ำ ซึ่งผลลัพธ์ที่ปรากฏคือ มีข้อมูลซ้ำ 258 แถว และ 4 แถว

     

    การกำจัดแถวที่มีข้อมูลซ้ำซ้อน
    เราสามารถกำจัดแถวที่มีข้อมูลซ้ำซ้อนกันได้โดยการใช้ rowid เข้ามาช่วย คราวนี้คุณต้องเลือกว่าจะเลือกเก็บข้อมูลแถวไหนไว้

    เราลองมาดูข้อมูลที่ควรจะเป็นที่ไม่ซ้ำกันว่ามีข้อมูลอะไรบ้าง โดยสามารถใช้คำสั่งได้ดังนี้

    select a,b,count(*) from test

    group by a,b;

    A          B   COUNT(*)

    ———- ———- ———-

    1          2        259

    2          2          5

    3          0          1

     

    กรณีที่ต้องการลบและคงเหลือไว้เฉพาะแถวแรกที่ซ้ำสามารถใช้คำสั่งได้ดังนี้

     

    เราต้องการกำจัด 258 แถวที่ซึ่ง A = 1 และ B = 2 บวกกับ

    — 4 แถวที่ซึ่ง A = 2 และ B = 2

    ลองมา select แถวที่เราจะคงไว้ดูก่อน

    select min(rowid),a,b from test

    group by a,b;

    MIN(ROWID)                             A          B

    ——————————- ———- ———-

    AAAAyvAAGAAAABYAAA          1          2

    AAAAyvAAGAAAABYAED          2          2

    AAAAyvAAGAAAABYAEI           3          0

     

    — คราวนี้ก็ถึงเวลาลบข้อมูลกันแล้ว

    — เริ่มกันเลย

    delete from test where rowid not in (

    select min(rowid) from test group by a,b);

    262 rows deleted.

     

    — คราวนี้มาตรวจสอบกันว่าข้อมูลที่คงเหลือถูกต้องหรือไม่

    select rowid,a,b from test;

    ROWID                                      A          B

    ——————————— ———- ———-

    AAAAyvAAGAAAABYAAA          1          2

    AAAAyvAAGAAAABYAED          2          2

    AAAAyvAAGAAAABYAEI           3          0

     

    กรณีที่ต้องการลบและคงเหลือไว้เฉพาะแถวสุดท้ายที่ซ้ำสามารถใช้คำสั่งได้ดังนี้

    delete from test where rowid not in (

    select max(rowid) from test group by a,b);

    262 rows deleted.

     

    แต่เพื่อป้องกันการเกิดการซ้ำซ้อนของข้อมูลเหล่านี้ เราสามารถที่จะใช้ unique constraints หรือ primary key ช่วยได้ ปัญหาข้อมูลซ้ำซ้อนแบบนี้ก็จะไม่มีทางเกิดขึ้นให้เกิดความปวดหัวได้อีก

     

  • อีกหนึ่งวิธีในการกำจัดข้อมูลที่ซ้ำซ้อนกันในตาราง

    ถ้าคุณมีตารางข้อมูลอยู่ และรู้ว่ามีบางแถวที่มีข้อมูลซ้ำซ้อนกัน ทางไหนเป็นวิธีที่ดีที่จะสามารถหาและกำจัดแถวที่มีข้อมูลซ้ำนี้ออกไปจากตารางของฐานข้อมูล Oracle ?

    อีกวิธีหนึ่งที่เป็นไปได้ในการกำจัดแถวที่ซ้ำซ้อนกันคือการใช้คำสั่ง select distinct และใส่ข้อมูลที่ได้ลงในตารางใหม่

     

    จากที่เราสามารถตรวจสอบหาข้อมูลแถวที่มีข้อมูลซ้ำซ้อนกันได้โดยใช้คำสั่ง select ดังนี้

    SQL> select a,b,count(*) from test group by a,b;

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

    A           B COUNT(*)
    ———- ———- ———-
    1           2       259
    2           2           5
    3           0           1

    จากตัวอย่างในตาราง test นี้ที่กำหนดไว้ว่าค่าในคอลัมภ์ a และ b จะต้องมีค่าไม่ซ้ำ ซึ่งผลลัพธ์ที่ปรากฏคือ มีข้อมูลซ้ำ 258 แถว และ 4 แถว

     

    เรามาเริ่มต้นกำจัดข้อมูลซ้ำซ้อนอีกวิธีกันเลย

     

    การหาแถวข้อมูลที่ไม่ซ้ำซ้อนกัน

    เราสามารถหาข้อมูลที่ไม่ซ้ำซ้อนกันได้โดยใช้คำสั่ง select distinct ดังนี้

    SQL> select distinct * from test;

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

             A           B
    ———- ———-
              1           2
              2           2
              3           0

     

    สร้างตารางใหม่ชั่วคราวเพื่อเก็บผลลัพธ์ที่ได้

    SQL> create table new_test as (select distinct * from test);

     

    ตรวจสอบผลลัพธ์ที่ได้ในตารางชั่วคราวนี้

    SQL> select * from new_test;

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

             A           B
    ———- ———-
              1           2
              2           2
              3           0 

     

    ทำการลบข้อมูลในตาราง test ทั้งหมด

    SQL> truncate table test;

    Table truncated.

     

    ทำการเพิ่มข้อมูลกลับไปยังตาราง test จากตารางชั่วคราว    

    SQL> insert into test (select * from new_test);

    3 rows created.

     

    ทำการลบตารางข้อมูลชั่วคราวทิ้ง

    SQL> drop table new_test;

    Table dropped.

     

    ตรวจสอบกันอีกครั้งว่าข้อมูลยังซ้ำกันอีกหรือไม่โดยใช้คำสั่ง select ดังนี้

    SQL> select a,b,count(*) from test group by a,b;

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

    A           B COUNT(*)
    ———- ———- ———-
    1           2           1
    2           2           1
    3           0           1

     

    นี่ก็เป็นอีกหนึ่งวิธีในการกำจัดแถวที่มีข้อมูลซ้ำซ้อนกันในตาราง แต่เพื่อป้องกันการเกิดการซ้ำซ้อนของข้อมูลเหล่านี้ ขอย้ำอย่าลืมใช้ unique constraints หรือ primary key ช่วยได้ ปัญหาข้อมูลซ้ำซ้อนแบบนี้ก็จะไม่มีทางเกิดขึ้นให้เกิดความปวดหัวได้อีก

  • What is MongoDB?

           MongoDB เป็น open-source document database ประเภทหนึ่ง โดยเป็น database แบบ NoSQL Database จะไม่มีการใช้คำสั่ง SQL ไม่เน้นในการสร้างความสัมพันธ์ของข้อมูลแต่จะเป็นรูปแบบโครงสร้างที่เจ้าของ NoSQL สร้างขึ้นมาเองและจัดเก็บข้อมูลเป็นแบบ JSON (JavaScript Object Notation) ซึ่งจะเก็บค่าเป็น key และ value โดยจุดเด่นอยู่ที่ความเร็วในการทำงานเป็นหลัก คิวรี่ข้อมูลได้เร็วขึ้น การทำงานในส่วนของ database จะลดลง แต่จะไปเน้นการทำงานในส่วนของโปรแกรมที่พัฒนาขึ้นมาแทน  โดย database ประเภทนี้ จะเหมาะกับข้อมูลขนาดใหญ่ ที่ไม่ซับซ้อน การทำงานที่ไม่หนักมาก สามารถทำงานกับระบบที่เป็นการทำงานแบบเรียลไทม์ (Real Time) ได้ดี

    รูปแบบการจัดเก็บ

    1. Collections การเก็บข้อมูล document ใน MongoDB จะถูกเก็บไว้ใน Collections เปรียบเทียบได้กับ Table ใน Relational Database ทั่วๆไป แต่ต่างกันที่ Collections ไม่จำเป็นที่จะต้องมี Schema เหมือนกันก็สามารถบันทึกข้อมูลได้
    2. Schemaless คือ การไม่ต้องกำหนดโครงสร้างใดๆให้มันเหมือน SQL ปกติทั่วไป เช่น Collection User มีเก็บแค่ name ต่อมาเราสามารถเพิ่มการเก็บ position เข้ามาได้เลย

    ข้อดีของ MongoDB

    1. MongoDB เป็น database แบบ Document-Oriented โดยลักษณะการเก็บข้อมูลจะใช้รูปแบบ format เป็น Json Style โดย Row แต่ละ Row ไม่จำเป็นต้องมีโครงสร้างข้อมูลเหมือนกัน เช่น

    [javascript]{

    data : “test”

    }[/javascript]

    1. MongoDB ใช้ระบบการจัดการ memory แบบเดียวกับ cached memory ใน linux ซึ่งจะปล่อยให้ OS เป็นคนจัดการ Memory
    2. ใช้ภาษา javascript เป็นคำสั่งในการจัดการข้อมูล
    3. MongoDB เป็น Full Index กล่าวคือรองรับข้อมูลมหาศาลมากๆ สามารถค้นหาจากส่วนไหนของข้อมูลเลยก็ได้
    4. MongoDB รองรับการ เพิ่ม หรือ หด field แบบรวดเร็ว ไม่ต้องใช้คำสั่ง Alter Table
    5. read-write ข้อมูลรวดเร็ว
    6. write ข้อมูล แบบ asynchronous (คล้าย INSERT DELAYED ของ MyISAM ใน MySQL) คือไม่ต้องรอ Insert เสร็จจริงก็ทำงานต่อได้
    7. MongoDB มี Capped Collection ซึ่งจะทยอยลบข้อมูลเก่าที่เก็บไว้นานเกินไปแล้วเอาข้อมูลใหม่มาใส่แทนได้ จะ clear ข้อมูลที่เก็บมานานเกินไปไว้ให้อัตโนมัติ ข้อมูลไม่โตกว่าที่เรากำหนด
    8. ค้นหาข้อมูลได้รวดเร็ว
    9. สามารถใช้เครื่อง server ที่ไม่ต้องคุณภาพสูงมากแต่แบ่งกันทำงานหลายๆเครื่อง ซึ่งประหยัดงบได้มากกว่าใช้เครื่องคุณภาพสูงเพียงเครื่องเดียว
    10. สามารถเขียนเป็นชุดคำสั่งได้ คล้ายๆกับการเขียน PL/SQL

     

    ข้อเสีย ของ MongoDB

    1. ถ้า project เก่ามีการ JOIN กันซับซ้อนก็จะเปลี่ยนมาใช้ MongoDB ได้ยาก
    2. กินพื้นที่การเก็บข้อมูลมากกว่า MySQL พอสมควร เพราะไม่มี Schema ดังนั้น Schema จริงๆจะอยู่ในทุก row ของฐานข้อมูล ทำให้ข้อมูลใหญ่กว่า MySQL
    3. หากใช้งานจน disk เต็ม จะ clear พื้นที่ disk ให้ใช้งานต่อยาก เพราะการสั่ง delete row ไม่ทำให้ฐานข้อมูลเล็กลง ต้องสั่ง compact เองซึ่งต้องมีที่ว่างที่ disk อีกลูกมากพอๆ กับพื้นที่ข้อมูลที่ใช้อยู่ปัจจุบันเป็น buffer ในการลดขนาด
    4. หากต้องการใช้งานเป็นฐานข้อมูลหลักแทน MySQL ควรมีเครื่องอย่างน้อย 3 เครื่องที่เป็น physical แยกกันทำ replication กัน เพื่อเพิ่ม durability ของข้อมูล เนื่องจากข้อมูลส่วนใหญ่ของ MongoDB จะเก็บใน Memory เป็นระยะเวลาหนึ่ง หากเครื่องดับไปเครื่อง ข้อมูลที่ยังค้างใน Memory แต่ยังไม่ write ลง disk จะสูญหายทันที

     

    คำสั่ง และ Mongo Shell เบื้องต้น

    กำหนดให้  collection = test การ Insert ข้อมูลใน Mongo Shell สามารถ save collection ได้ง่ายๆด้วย db.collectionName.save()

    db.test.save({a: 1, b: 2, c: 3})  –save ข้อมูลลง collectionName “test”

    หรือ

    db.test.save([

    { name: ‘Maliwan’ },

    { name: ‘BentoBarbeque’ }

    ]);     –save ข้อมูลลง collectionName “test”

     

    การ Query

    การค้นหาข้อมูล ใน Mongo Shell จะใช้คำสั่ง db.collectionName.find()

    db.test.find()       — ค้นหาข้อมูลทั้งหมดจาก  collectionName “test”

     

    การค้นหาโดยใส่เงื่อนไข

    db.test.find({name: ‘Maliwan’}) — ค้นหา collection test ที่มี name = Maliwan

     

    การ Update

    การ Update ข้อมูล เราจะใช้ $set operator

    db.test.update(

    {‘name’: ‘Maliwan’},

    {

    $set: {‘company’: ‘psu’}

    })    

    –ทำการ query หา collection test ที่มี name = Maliwan จากนั้นก็ทำการ update โดยเพิ่ม company ให้มีค่า ‘psu’

     

    การ Remove

    การลบข้อมูลใน MongoDB จะใช้ remove()

    db.test.remove({name: ‘Maliwan’});  –ลบข้อมูล collection test ที่ name = Maliwan ทั้งหมด

    หากต้องการกำหนดว่าให้ลบแค่ 1 record ด้วย flag justOne

    db.test.remove({name: ‘Maliwan’}, {justOne: true})   –ลบข้อมูล collection test ที่ name = Maliwan เพียง 1 record ถึงแม้จะเจอมากกว่า 1 record

     

     

     

    สามารถอ่านข้อมูลและศึกษาเพิ่มเติมได้

    https://www.mongodb.com/who-uses-mongodb

    ส่วนการติดตั้ง database สามารถเข้าไปเพิ่มเติมได้จาก

    http://docs.mongodb.org/manual/installation/