ThaiSEOBoard.com

พัฒนาเว็บไซต์ => Programming => ข้อความที่เริ่มโดย: nat-ns ที่ 28 มิถุนายน 2016, 18:27:26



หัวข้อ: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nat-ns ที่ 28 มิถุนายน 2016, 18:27:26
เนื่องจากเว็บที่กำลังจะทำนั้น มีการอัพเดทข้อมูลที่ถี่มาก เช่นส่วนของการนับแต้ม ที่จะเก็บ Score จากหลายๆที่โดยไม่อาจคาดเดาได้ว่าแต้มเหล่านั้นจะถูกบันทึกมาจากใครและที่ใด

สมมตินาย A มีแต้ม 200 แล้ว นาย B,C,...N ส่งแต้มมาให้ โดยให้แบบพร้อมกันบ้างไม่พร้อมกันบ้าง แต่ให้ตลอดเวลา ปัญหาที่เกิดคือข้อมูล อาจจะชนกันได้ ดังนั้นผมถึงได้หาวิธีแก้ปัญหาโดยใช้ INNODB เพื่อสามารถควบคุมการ Lock ระดับแถวได้ และตอน SELECT SCORE เก่าผมก็ใช้คำสั่ง FOR UPDATE เข้ามาช่วยเพื่อไม่ให้คนอื่นสามารถมาทำรายการได้แล้วคนที่อ่านลำดับถัดไป หรือในเวลาเดียวกันต้องได้ค่า score ล่าสุดที่ถูกต้องนะ

ปัญหาคือผมยังไม่เคยเจอสถานณ์ที่ข้อมูลวิ่งกันขนาดนนี้เลยไม่รู้ว่าวิธีใดเหมาะสมที่สุดในการเขียนคำสั่ง SQL ในการนำเอา SCORE มา UPDATE ดังนั้นผมจึงอยากขอประสบการณ์จากทุกท่าน ช่วยเล่าหรือแนะนำ วิธีที่ผมใช้(ได้มากจากคำแนะนำจากหลายท่านในหลายที่) นั้นเหมาะสมหรือไม่ แล้วมีวิธีใดที่ดีกว่า เพราะผมไม่อยากให้ระบบตอบสนองช้าเนื่องจากคิวที่รอยาวเกินไป และไม่อยากให้ข้อมูลชนกันจนค่า Score ผิดเพี้ยน เพราะเป็นหน่วยที่สำคัญมากๆ เพราะเป็นเรื่องของเงินๆทองๆจริงๆครับ เสียหายมาผมคงกุมขมับแน่ๆ ดังนั้นจึงขอความอนุเคราะห์ จากประสบการณ์ของหลายๆท่าน

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

โค๊ด:
<?php

// Create connection
//$conn = new mysqli($servername, $username, $password, $dbname);
$conn mysql_connect("localhost","root","") or die("Error Connect to Database");
mysql_select_db("testtran");
//*** Start Transaction ***//
mysql_query("START TRANSACTION");

$sql    "SELECT point FROM test FOR UPDATE";
$result mysql_query$sql,$conn);
$row    mysql_fetch_assoc($result);
print_r($row);
//echo $row['point'];
mysql_query("SET GLOBAL autocommit=0");
Sleep(5);

$point $row['point']+100;
$sql "UPDATE test SET point=".$point." WHERE name='nscyber'";
$objQuery1 mysql_query($sql,$conn);

if(
$objQuery1)
{

mysql_query("COMMIT");
echo "Save Done.";
}
else
{

mysql_query("ROLLBACK");
echo "Error Save";
}
//mysqli_close($conn);
mysql_close($conn);
?>


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: rapiz ที่ 28 มิถุนายน 2016, 18:29:48
ลองไปเรียนรู้เรื่อง ISOLATION LEVEL ของ mysql นะคับ เพราะว่าสำคัญ

ใช้ในการ lock row หรือ session เพื่อไม่ให้ transaction ใหม่เข้ามายุ่ง ถ้ายังไม่ commit

ควรจะใช้ mysqli แทน mysql ได้แล้วนะคับ


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: jira2712 ที่ 28 มิถุนายน 2016, 18:41:29
$filename="xxxx.txt";
$fp=fopen($filename,"r");
$number=fread($fp,filesize($filename));
fclose($fp);
$number=$number+1;
$fp=fopen($filename,"w");
fwrite($fp,$number);
fclose($fp);

ผมไม่แน่ใจนะ เพิ่มค่าตัวแปร อีกตัวครับ บนสุดของฐานข้อมูลน่าจะจัดเรียงได้ดีครับ


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: jira2712 ที่ 28 มิถุนายน 2016, 18:55:28
หรือใช้ค่าตัวแปรเวลาก็ได้ครับ ดีกว่า


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nat-ns ที่ 28 มิถุนายน 2016, 20:39:10
ลองไปเรียนรู้เรื่อง ISOLATION LEVEL ของ mysql นะคับ เพราะว่าสำคัญ

ใช้ในการ lock row หรือ session เพื่อไม่ให้ transaction ใหม่เข้ามายุ่ง ถ้ายังไม่ commit

ควรจะใช้ mysqli แทน mysql ได้แล้วนะคับ

ครับ ผมลองดูไประยะนึงแล้วแต่ว่ายังไม่แน่ใจเรื่องคำสั่งในการเขียน เช่น SELECT สามารถ Lock ได้โดยใช้ FOR UPDATE ถ้ามีคนอื่นที่เรียกในแถวเดียวกันอยู่มันจะรอจนกว่าคนที่มาก่อนทำเสร็จก่อน(จากที่ทดสอบนะครับแต่ไม่รุ้เข้าใจถูกไหม) แล้วจึงนำค่านั้นไปใส่ใน UPDATE

แต่ว่าบางท่านแนะนำว่าให้ใส่ตัวเลขไปตรงๆเลยเช่นปกติใช้ แบบ SELECT ก่อนแล้วเอาค่าที่ SELECT ได้ไปบวกค่าใหม่ให้เรียบร้อยแล้วค่อย UPDATE ดังโค้ด

โค๊ด:
$sql    = "SELECT point FROM test FOR UPDATE";
$result = mysql_query( $sql,$conn);
$row    = mysql_fetch_assoc($result);

$point = $row['point']+100;
$sql = "UPDATE test SET point=".$point." WHERE name='nscyber'";
$objQuery1 = mysql_query($sql,$conn);

แต่บางท่านบอกว่าทำไมไม่ใส่ใน UPDATE ไปเลยละแบบโค้ดด้านล่าง จะไป SELECT ทำไม เพื่อลดข้อผิดพลาดของ SELECT

โค๊ด:
$sql = "UPDATE test SET point=point+100 WHERE name='nscyber'";
$objQuery1 = mysql_query($sql,$conn);

แต่ปัญหาคือถ้าใช้แบบแรก SELECT ก่อน มันจะมีคำสั่ง FOR UPDATE มาช่วยในการป้องกันการชนกัน แต่สำหรับ UPDATE เราจะใช้คำสั่งอะไรในการป้องกัน

------------
ส่วนในเรื่องของ  ISOLATION LEVEL ซึ่งก็ต้องระวังในเรื่องของ Deadlock ตรงนี้ก็เป็นอีกปัญหาหนึ่งที่ อยากขอคำแนะนำครับว่ามีวิธีการป้องกันไหนที่เหมาะสมกับงานลักษณะนี้ไหมครับ หรือจุดที่ต้องมองเป็นพิเศษ เพราะข้อมูลมีการอัพเดทตลอดเวลา

 :wanwan019:



หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nat-ns ที่ 28 มิถุนายน 2016, 20:41:17
$filename="xxxx.txt";
$fp=fopen($filename,"r");
$number=fread($fp,filesize($filename));
fclose($fp);
$number=$number+1;
$fp=fopen($filename,"w");
fwrite($fp,$number);
fclose($fp);

ผมไม่แน่ใจนะ เพิ่มค่าตัวแปร อีกตัวครับ บนสุดของฐานข้อมูลน่าจะจัดเรียงได้ดีครับ

อันนี้คือบันทึกอะไรหรอครับ  :P


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: xvlnw.com ที่ 28 มิถุนายน 2016, 20:48:43
ถ้าค่านั้นๆที่ต้องการอัพเดตเข้าไป ไม่จำเป็นที่จะต้อง Query ออกมาเพื่อคำนวนบางอย่าง ใช้วิธี point=point+100 แบบนี้ผมคิดว่าไม่น่าจะเกิดการซ้ำซ้อนของข้อมูลนะครับ #NotSure #NotTest


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: MapTwoZa ที่ 28 มิถุนายน 2016, 23:55:18
ถ้าค่านั้นๆที่ต้องการอัพเดตเข้าไป ไม่จำเป็นที่จะต้อง Query ออกมาเพื่อคำนวนบางอย่าง ใช้วิธี point=point+100 แบบนี้ผมคิดว่าไม่น่าจะเกิดการซ้ำซ้อนของข้อมูลนะครับ #NotSure #NotTest

ซ้ำได้ครับ มันไม่ thread safe



TO จขกท
ทำไมต้องทำ Pessimistic Read ครับ
เวลา select ถ้าข้อมูลไม่ตรง มัน sensitive ขนาดนั้นเลยหรอ refresh ใหม่ก็ตรงละมั้งเพราะ Pessimistic Read มันกินมาก
ผมมองว่า Pessimistic Write ก็พอครับ เอาให้มัน update ถูกพอละครับ ได้ไม่เปลืองมาก (ถ้าไม่เน้น performance ก็ไม่เป็นไร)

1. เวลา lock ก็ lock เฉพาะ row ที่จะ update พอ
2. update เสร็จก็ Unlock เลย
หลักการมันมีแค่นั้นแหละครับ

อ้างถึง
แต่ปัญหาคือถ้าใช้แบบแรก SELECT ก่อน มันจะมีคำสั่ง FOR UPDATE มาช่วยในการป้องกันการชนกัน แต่สำหรับ UPDATE เราจะใช้คำสั่งอะไรในการป้องกัน
ก็ Select for update แหละครับ ไว้ใช้ lock ก่อน Update -*-

ปล. ถ้าเน้น concurrency + performance ไม่ควร lock ที่ DB Level ครับ มันคอขวด ควร lock ที่ Thread Level (ซึ่ง PHP ทำไม่ได้ 555+)


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: kingofdollars ที่ 29 มิถุนายน 2016, 06:09:49
แนะนำว่าทำระบบ ตรวจทาน คล้ายๆที่ธนาคารเขาทำครับ  หาเวลา run ตอน traffic ต่ำๆครับ


นั้นคือ ทุก transaction ที่เข้ามาเก็บลงระบบให้หมดครับ  แล้วก็ update ไปตามเรื่อง

พอถึงเวลาที่กำหนด ก็ run crone ซึ่งทำวันละครั้ง

เอา balance ล่าสุดของวันที่แล้วมา แล้ววิ่ง process ทุก transaction ใหม่อีกที แล้วเทียบกับ balance สุดท้ายของที่ดำเนินการมาแล้ว ถ้าตรงก็รอดตัว

ถ้าไม่ตรงก็เอาของเก่าออกหมด จับตัวใหม่ยัดเข้าไป  ระหว่างนี้อย่าลืมปิดระบบการรับข้อมูลใหม่เข้ามาด้วยนะครับ

หลายๆ ธนาคาร เขารันระบบแนวนี้ราวๆ ห้าทุ่ม ก่อนจะเริ่มวันใหม่นะครับ  จะเห็นว่าช่วงเวลานี้บางที ตู้ ATM จะถอนเงินไม่ได้ ธนาคารออนไลน์เข้าไม่ได้ หรือเข้าไปเจอตัวเลขมั่วตั้วมาก


วิธีแบบนี้ทำให้เราสามารถเอาข้อมูล transaction เก่าเกิน 6 เดือนไป backup เอาไว้เผื่อมีปัญหา หลังจากนั้นก็  clean table นั้นใหม่ทำให้ DB ไม่หนักอีกด้วย

เคยทำระบบ payment processor มา  แค่ใช้ระบบ mysql update ธรรมดา ก็ยังไม่เคยเจอปัญหา transaction ซ้อนกันมากนัก อาศัยว่าเก็บทุก transaction ที่เข้ามาลง DB ก่อน แล้วเวลาคำนวน ยอดเงิน ก็คำนวนจาก ยอด balance ล่าสุด หักลบใน transaction แล้วบันทึกค่าใหม่ลงที่แต่ละ user พร้อม encryption เรียบร้อย  แล้วก็เก็บตัวเลข balance รวมเอาไว้สอบทาน ว่าทุก user รวมกันต้องตรงกับ balance รวม  หักค่าธรรมเนียม ฝั่งถอน ฝั่งฝาก ก็ไม่เคยเจอที่ว่ายอดไม่ตรงกัน

ไว้เป็นแนวทางนะครับ  เพราะหากเราเก็บแค่ balance รวมอย่างเดียว เวลาเจอปัญหา แก้ยากครับ ไม่รู้ว่าของใครซ้ำไม่ซ้ำ แต่แบบนี้เราสอบทานความสอดคล้องของข้อมูลฝั่งจ่ายกับฝั่งรับได้เสมอ drill down ลงไปได้ทางฝั่ง admin


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: evev9 ที่ 29 มิถุนายน 2016, 08:13:39
เข้ามาฟังด้วยครับ  :wanwan017:


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: postmunnet ที่ 29 มิถุนายน 2016, 08:30:35
ผมทำ 2 table

table แรก ผมเก็บข้อมูลว่าใครส่งให้ใครส่งไปเท่าไหร่ ร่วมกับเวลา และ status check ว่าเอามาคำนวณแล้ว
table สอง ผมเก็บค่า total

จากนั้นผมจะอัพเดตด้วย cronjob ทุก 1 นาที เอาค่าที่ยังไม่คำนวณมาคำนวณ total ตามที่บันทึกไว้ แล้ว update status check
ไม่แน่ใจว่าที่คิดนี่ถูกหรือดีป่าวนะแต่ถ้าตัวเองทำจะประมาณนี้พร้อมแจ้ง user ว่าต้องรอประมาณ 1 นาทีถึงจะเห็นการเปลี่ยนแปลง


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nat-ns ที่ 29 มิถุนายน 2016, 11:00:32
ถ้าค่านั้นๆที่ต้องการอัพเดตเข้าไป ไม่จำเป็นที่จะต้อง Query ออกมาเพื่อคำนวนบางอย่าง ใช้วิธี point=point+100 แบบนี้ผมคิดว่าไม่น่าจะเกิดการซ้ำซ้อนของข้อมูลนะครับ #NotSure #NotTest

ซ้ำได้ครับ มันไม่ thread safe



TO จขกท
ทำไมต้องทำ Pessimistic Read ครับ
เวลา select ถ้าข้อมูลไม่ตรง มัน sensitive ขนาดนั้นเลยหรอ refresh ใหม่ก็ตรงละมั้งเพราะ Pessimistic Read มันกินมาก
ผมมองว่า Pessimistic Write ก็พอครับ เอาให้มัน update ถูกพอละครับ ได้ไม่เปลืองมาก (ถ้าไม่เน้น performance ก็ไม่เป็นไร)

1. เวลา lock ก็ lock เฉพาะ row ที่จะ update พอ
2. update เสร็จก็ Unlock เลย
หลักการมันมีแค่นั้นแหละครับ

อ้างถึง
แต่ปัญหาคือถ้าใช้แบบแรก SELECT ก่อน มันจะมีคำสั่ง FOR UPDATE มาช่วยในการป้องกันการชนกัน แต่สำหรับ UPDATE เราจะใช้คำสั่งอะไรในการป้องกัน
ก็ Select for update แหละครับ ไว้ใช้ lock ก่อน Update -*-

ปล. ถ้าเน้น concurrency + performance ไม่ควร lock ที่ DB Level ครับ มันคอขวด ควร lock ที่ Thread Level (ซึ่ง PHP ทำไม่ได้ 555+)


ขอบคุณครับ

อ้างถึง
เวลา select ถ้าข้อมูลไม่ตรง มัน sensitive ขนาดนั้นเลยหรอ refresh ใหม่ก็ตรงละมั้ง
sensitive มากครับ ระบบจะ select ในสคริปครับสมาชิกจะมองไม่เห็น ไม่มีการโชว์ยอดหลังคำนวณก่อนบันทึกครับ มันเป็นยอดเงินของสมาชิกที่เก็บไว้ในระบบน่ะครับ ถ้าเป็นแบบเว็บขายสิ้นค้าอันี้ใช้แบบนั้นได้ครับ

แล้วก็ Select for update ผมชอบครับตรงตามที่ต้องการเพียงแต่ถ้าคิวแรกๆอืดเมื่อไรคอวต่อๆไป จะรอนานมากครับ



หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nat-ns ที่ 29 มิถุนายน 2016, 11:12:44
แนะนำว่าทำระบบ ตรวจทาน คล้ายๆที่ธนาคารเขาทำครับ  หาเวลา run ตอน traffic ต่ำๆครับ


นั้นคือ ทุก transaction ที่เข้ามาเก็บลงระบบให้หมดครับ  แล้วก็ update ไปตามเรื่อง

พอถึงเวลาที่กำหนด ก็ run crone ซึ่งทำวันละครั้ง

เอา balance ล่าสุดของวันที่แล้วมา แล้ววิ่ง process ทุก transaction ใหม่อีกที แล้วเทียบกับ balance สุดท้ายของที่ดำเนินการมาแล้ว ถ้าตรงก็รอดตัว

ถ้าไม่ตรงก็เอาของเก่าออกหมด จับตัวใหม่ยัดเข้าไป  ระหว่างนี้อย่าลืมปิดระบบการรับข้อมูลใหม่เข้ามาด้วยนะครับ

หลายๆ ธนาคาร เขารันระบบแนวนี้ราวๆ ห้าทุ่ม ก่อนจะเริ่มวันใหม่นะครับ  จะเห็นว่าช่วงเวลานี้บางที ตู้ ATM จะถอนเงินไม่ได้ ธนาคารออนไลน์เข้าไม่ได้ หรือเข้าไปเจอตัวเลขมั่วตั้วมาก


วิธีแบบนี้ทำให้เราสามารถเอาข้อมูล transaction เก่าเกิน 6 เดือนไป backup เอาไว้เผื่อมีปัญหา หลังจากนั้นก็  clean table นั้นใหม่ทำให้ DB ไม่หนักอีกด้วย

เคยทำระบบ payment processor มา  แค่ใช้ระบบ mysql update ธรรมดา ก็ยังไม่เคยเจอปัญหา transaction ซ้อนกันมากนัก อาศัยว่าเก็บทุก transaction ที่เข้ามาลง DB ก่อน แล้วเวลาคำนวน ยอดเงิน ก็คำนวนจาก ยอด balance ล่าสุด หักลบใน transaction แล้วบันทึกค่าใหม่ลงที่แต่ละ user พร้อม encryption เรียบร้อย  แล้วก็เก็บตัวเลข balance รวมเอาไว้สอบทาน ว่าทุก user รวมกันต้องตรงกับ balance รวม  หักค่าธรรมเนียม ฝั่งถอน ฝั่งฝาก ก็ไม่เคยเจอที่ว่ายอดไม่ตรงกัน

ไว้เป็นแนวทางนะครับ  เพราะหากเราเก็บแค่ balance รวมอย่างเดียว เวลาเจอปัญหา แก้ยากครับ ไม่รู้ว่าของใครซ้ำไม่ซ้ำ แต่แบบนี้เราสอบทานความสอดคล้องของข้อมูลฝั่งจ่ายกับฝั่งรับได้เสมอ drill down ลงไปได้ทางฝั่ง admin

เอิ่มเดี๋ยวนะครับผมอ่านยังงงๆนิดๆ  :P

ก็คือทุกครั้งที่มีการทำรายการ ให้บันทึก transaction ไว้ด้วย พอถึงเวลาให้หาสักช่วงเวลา มาตรวจทานก่อนขึ้นวันใหม่ โดยเอา balance ของวันเก่ามารันกับ transaction วันใหม่โว่ายอดที่คำนวณสุดท้ายนั้นตรงกับ balance ล่าสุดหรือไม่ ถ้าตรงก็โอเค

ถ้าไม่ตรงก็ "ถ้าไม่ตรงก็เอาของเก่าออกหมด จับตัวใหม่ยัดเข้าไป " อันนี้ผมยังไม่เข้าใจครับคือ "เอาของเก่าออกหมด" นี่คือเอาอะไรออกรอครับ ค่าเงินล่าสุดหรอครับ ที่ผมเข้าใจคือสมมติตรวจ transaction  แล้วยอดต้องเป็น 3500 แต่ balance ล่าสุดเป็น 3000 ก็เอา 3500 เข้าไปแทน อย่างนี้หรือป่าวครับ
-----------------------------
อ้างถึง
เวลาคำนวน ยอดเงิน ก็คำนวนจาก ยอด balance ล่าสุด หักลบใน transaction แล้วบันทึกค่าใหม่ลงที่แต่ละ user

ทำไมถึงนำค่า ยอด balance ล่าสุด หักลบใน transaction หรอครับ ทำไมไม่หักลบกับ ยอดที่ระบบรับมา ณ ตอนนั้นแล้วบันทึกเลย
-----------------------------
อ้างถึง
พร้อม encryption เรียบร้อย 

ปกติท่าน encryption อะไรบ้างครับ อยากขอเป็นความรู้นิดนึงครับ ปกติผมจะ encryption พวกรหัสผ่านมากกว่า พวกยอดเงินหรืออะไรผมไม่รุ็ว่าทางระบบใหญ่ๆ เขา encryption ข้อมูลสำคัญอะไรบ้าง

ขอขอบคุณครับ


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nat-ns ที่ 29 มิถุนายน 2016, 11:14:48
ผมทำ 2 table

table แรก ผมเก็บข้อมูลว่าใครส่งให้ใครส่งไปเท่าไหร่ ร่วมกับเวลา และ status check ว่าเอามาคำนวณแล้ว
table สอง ผมเก็บค่า total

จากนั้นผมจะอัพเดตด้วย cronjob ทุก 1 นาที เอาค่าที่ยังไม่คำนวณมาคำนวณ total ตามที่บันทึกไว้ แล้ว update status check
ไม่แน่ใจว่าที่คิดนี่ถูกหรือดีป่าวนะแต่ถ้าตัวเองทำจะประมาณนี้พร้อมแจ้ง user ว่าต้องรอประมาณ 1 นาทีถึงจะเห็นการเปลี่ยนแปลง

ขอบคุณครับ เหมือนวิธีนี้น่าจะติดปัญหาตรงถ้ามีสมาชิกทำรายการเยอะๆ หลายๆคน ณ เวลานั้น อาจจะต้องรอมากกว่า 1 นาที เพราะระบบอาจจะต้องเช็คทีละคน


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: kingofdollars ที่ 29 มิถุนายน 2016, 16:47:01
ผมอธิบายใหม่ในประเด็นที่คุณสงสัยนะครับ

เนื่องจากเป็นระบบปิด เงินทุกยอดรวมกันต้องได้ ตัวเลขคงที่เสมอ ดังนั้นจึงมีบัญชีระบบอยู่ด้วยคือ

SYSTEM = 1,000,000 ล้านเป็นต้น

เริ่มแรกถ้าใครฝากเงิน Admin จะต้องโอนเงินจากระบบเข้า A เช่น A ฝาก 1000
B ฝาก 2000  ก็จะได้

SYSTEM -> A 1,000
SYSTEM -> B 2,000

เกิดรายการ
1. SYSTEM -1000 
2 A +1000
3 SYSTEM -2000
4 B +2000

หาก A ถอนเงิน 500 ก็จะเกิด
A -> SYSTEM 500
เกิดรายการ
1. A - 500
2 SYSTEM + 500

แต่ละ  User คือ A,B... System  ก็จะมี  Balance เกาะติดอยู่ด้วย จำนวน 2 balance คือ Balance ปัจจุบันตอนนี้ กับ Balance ล่าสุดจากเที่ยงคืนเมื่อวาน

ดังนั้นรวมทุก Balance ก็จะเป็น 1,000,000 เท่าเดิม

คราวนี้ถึงจุดหนึ่งในเวลาผ่านไป

สมมุติมีรายการเข้ามาติดๆ กัน 5 รายการ ตัวอย่างง่ายๆนะครับ

1 A -> B 20
2 C -> D 10
3 B -> C 10
4 B -> A 10
5 A -> D 10


จะเกิด transaction ที่ต้องใส่ DB ที่ชื่อว่า transaction  โดยจะต้องใส่ Hash จับคู่ฝั่งโอนเข้า โอนออกในแต่ละรายการ
หนึ่งรายการ (2 row) จะต้องมี hash เดียวกันไม่ซ้ำกับอย่างอื่น โดยการเอา DB ID ของคนโอนออกมาใช้ในการ hash
1 A - 20
2 B + 20
3 C - 10
4 D -10
5 B -10
6 C +10
7 B -10
8 A +10
9 A -10
10 D + 10

การเกิดแต่ละ transaction ก็จะมีการหักลบ Balance ปัจจุบันไปเรื่อยๆ เพื่อจะได้แสดงยอดเงินได้อย่างรวดเร็ว
แต่ละคนเองจะเห็นรายการที่เกิดขึ้นในฝั่งตัวเองเท่านั้น ดังนั้นใน table transaction จะมีว่า จำนวนเงิน สถานะโอนเข้าหรือออก หรือจะใส่สองคอลัมน์ เข้า 0 ออก 10 ถ้าโอนออก หรือ เข้า 10 ออก 0 ถ้าโอนเข้า แล้วแต่สะดวก

เวลาเราแสดงยอดเงินให้กับ ลูกค้าก็เอาผลการคำนวนสุดท้ายหรือ Balance สุดท้ายมาแสดง


พอถึงสิ้นวัน เริ่มตรวจสอบระบบใหม่ ว่ายอดเงินทุกคนรวมกัน รวมกับ SYSTEM เท่าเดิมหรือไม่
ถ้าเท่าก็รอดตัว แต่ถ้าไม่เท่ากัน เราจะเห็นว่ารายการไหนมันเพิ่มเข้ามาผิดปกติ

พวกรายการเดียว ข้ามไป
พวกหลายรายการ ตรวจสอบว่า Hash transaction ID ซ้ำกันหรือไม่
ถ้าซ้ำรายการไหน ก็มาทำ algorithm ปรับค่าแสดงผลให้ admin ทราบอีกที  แล้วก็ปรับค่า Balance ใหม่
ตอนนี้ Balance เมื่อวาน ก็จะเท่ากับวันนี้แล้ว

ประมาณนี้นะครับ 
เพราะถ้าไม่ทำแบบนี้ จะไม่มีวันรู้ว่าใครแอบเติมเงินเข้าฐานข้อมูลบ้าง

-----

การ encrypt ยอดเงินในฐานข้อมูลเก็บทั้งตัวเลข และ hash
การ  hash เอาทั้ง user id + ยอดเงิน + เกลือ แล้วเก็บในฐานข้อมูลใน transaction นั้นๆ
เมื่อไหร่ที่ยอดเงินถูกแก้ hash ไม่ตรง ก็ห้ามโอน ให้แจ้งเตือน

นั่นแสดงว่า ทุกครั้งก่อนโอนตร้องตรวจ hash ก่อน
รับเงินมาแล้ว สร้าง hash ใหม่ทุกครั้งไป

พบว่า ใน host บางที แฮกเกอร์เข้ามาเปลียนข้อมูลใน DB เฉยเลยครับ


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: niae617 ที่ 29 มิถุนายน 2016, 17:35:30
เยียม


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: xvlnw.com ที่ 29 มิถุนายน 2016, 18:54:12
นี่จะเป็นมู้คุณภาพแห่งปีนี้ต่อไป, สาระล้วนๆ  :wanwan020: :wanwan020:


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: thanarack ที่ 29 มิถุนายน 2016, 22:46:52
ปกติ mysql มันต่อคิวเข้าทำงานอยู่แล้วนะครับ หรือยังไง


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: kingofdollars ที่ 29 มิถุนายน 2016, 23:53:21
ปกติ mysql มันต่อคิวเข้าทำงานอยู่แล้วนะครับ หรือยังไง

ใช่แล้วครับ มันไม่ใช่ปัญหาที่ SQL แต่เป็นปัญหาขอวการออกแบบครับ ในเชิงวิขาการเขาเรียกว่า Last Seat Problem ครับ

ตัวอย่างเช่น สายการบินหนึ่งมีที่ว่าง เหลืออีก 1 ที่นั่งเท่านั้น

ระหว่างนั้น Agent A เช็คเข้ามาก็ว่าง 1 ที่
ขณะเดียวกัน Agent B ก็เช็คเข้ามาเห็นว่า 1 ที่  ซึ่งเป็นอันเดียวกันกับที่ A เห็น

ลูกค้าของทั้งสองฝั่ง ยืนยันจองทันที ในเวลาพร้อมๆ กัน

ปัญหาคือ ใครจะได้ที่สุดท้ายนั้นไป

กรณีนี้ก็คล้ายๆ กัน  คือมีเงินอยู่ 100 นึง แล้วเปิด 2 หน้าเว็บพร้อมๆกัน แล้วกดโอนออกไปคนละ 100 เท่ากัน เอ้ะจะเกิดอะไรขึ้น

จะพบว่าถ้าเขียนโค้ดธรรมดา รายการแรก หักไป 100 เงินเหลือ 0 รายการต่อมาหักอีก 100 เงินก็ติดลบ -100

ปัญหานี้ทำให้โปรแกรมเมอร์สมัครเล่นโดนด่ามานักต่อนักแล้ว


คราวนี้จินตนาการว่า คนนี้สั่งโอนแต้มให้คนโน้น มั่วตั้วไปหมด จะออกแบบอย่างไรไม่ให้เกิดปัญหาแบบข้างต้นนั่นเอง


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nat-ns ที่ 30 มิถุนายน 2016, 02:33:57
ผมอธิบายใหม่ในประเด็นที่คุณสงสัยนะครับ

เนื่องจากเป็นระบบปิด เงินทุกยอดรวมกันต้องได้ ตัวเลขคงที่เสมอ ดังนั้นจึงมีบัญชีระบบอยู่ด้วยคือ

SYSTEM = 1,000,000 ล้านเป็นต้น

เริ่มแรกถ้าใครฝากเงิน Admin จะต้องโอนเงินจากระบบเข้า A เช่น A ฝาก 1000
B ฝาก 2000  ก็จะได้

SYSTEM -> A 1,000
SYSTEM -> B 2,000

เกิดรายการ
1. SYSTEM -1000 
2 A +1000
3 SYSTEM -2000
4 B +2000

หาก A ถอนเงิน 500 ก็จะเกิด
A -> SYSTEM 500
เกิดรายการ
1. A - 500
2 SYSTEM + 500

แต่ละ  User คือ A,B... System  ก็จะมี  Balance เกาะติดอยู่ด้วย จำนวน 2 balance คือ Balance ปัจจุบันตอนนี้ กับ Balance ล่าสุดจากเที่ยงคืนเมื่อวาน

ดังนั้นรวมทุก Balance ก็จะเป็น 1,000,000 เท่าเดิม

คราวนี้ถึงจุดหนึ่งในเวลาผ่านไป

สมมุติมีรายการเข้ามาติดๆ กัน 5 รายการ ตัวอย่างง่ายๆนะครับ

1 A -> B 20
2 C -> D 10
3 B -> C 10
4 B -> A 10
5 A -> D 10


จะเกิด transaction ที่ต้องใส่ DB ที่ชื่อว่า transaction  โดยจะต้องใส่ Hash จับคู่ฝั่งโอนเข้า โอนออกในแต่ละรายการ
หนึ่งรายการ (2 row) จะต้องมี hash เดียวกันไม่ซ้ำกับอย่างอื่น โดยการเอา DB ID ของคนโอนออกมาใช้ในการ hash
1 A - 20
2 B + 20
3 C - 10
4 D -10
5 B -10
6 C +10
7 B -10
8 A +10
9 A -10
10 D + 10

การเกิดแต่ละ transaction ก็จะมีการหักลบ Balance ปัจจุบันไปเรื่อยๆ เพื่อจะได้แสดงยอดเงินได้อย่างรวดเร็ว
แต่ละคนเองจะเห็นรายการที่เกิดขึ้นในฝั่งตัวเองเท่านั้น ดังนั้นใน table transaction จะมีว่า จำนวนเงิน สถานะโอนเข้าหรือออก หรือจะใส่สองคอลัมน์ เข้า 0 ออก 10 ถ้าโอนออก หรือ เข้า 10 ออก 0 ถ้าโอนเข้า แล้วแต่สะดวก

เวลาเราแสดงยอดเงินให้กับ ลูกค้าก็เอาผลการคำนวนสุดท้ายหรือ Balance สุดท้ายมาแสดง


พอถึงสิ้นวัน เริ่มตรวจสอบระบบใหม่ ว่ายอดเงินทุกคนรวมกัน รวมกับ SYSTEM เท่าเดิมหรือไม่
ถ้าเท่าก็รอดตัว แต่ถ้าไม่เท่ากัน เราจะเห็นว่ารายการไหนมันเพิ่มเข้ามาผิดปกติ

พวกรายการเดียว ข้ามไป
พวกหลายรายการ ตรวจสอบว่า Hash transaction ID ซ้ำกันหรือไม่
ถ้าซ้ำรายการไหน ก็มาทำ algorithm ปรับค่าแสดงผลให้ admin ทราบอีกที  แล้วก็ปรับค่า Balance ใหม่
ตอนนี้ Balance เมื่อวาน ก็จะเท่ากับวันนี้แล้ว

ประมาณนี้นะครับ 
เพราะถ้าไม่ทำแบบนี้ จะไม่มีวันรู้ว่าใครแอบเติมเงินเข้าฐานข้อมูลบ้าง

-----

การ encrypt ยอดเงินในฐานข้อมูลเก็บทั้งตัวเลข และ hash
การ  hash เอาทั้ง user id + ยอดเงิน + เกลือ แล้วเก็บในฐานข้อมูลใน transaction นั้นๆ
เมื่อไหร่ที่ยอดเงินถูกแก้ hash ไม่ตรง ก็ห้ามโอน ให้แจ้งเตือน

นั่นแสดงว่า ทุกครั้งก่อนโอนตร้องตรวจ hash ก่อน
รับเงินมาแล้ว สร้าง hash ใหม่ทุกครั้งไป

พบว่า ใน host บางที แฮกเกอร์เข้ามาเปลียนข้อมูลใน DB เฉยเลยครับ



โหขอบคุณจริงๆครับ พอเห็นภาพระดับนึงครับ ตอนแรกก็งงๆอ่านไปสามสี่รอบ ก็คือเราต้องมี SYSTEM ไว้สำหรับคอยตรวจเช็คเงิน หากวันดีคืนดีมีแฮกเกอร์แอบย่องเข้ามาเติมตัวเลขเข้าไปยอดมันจะเกิน ตามที่ตั้งไว้
- ถ้าอย่างงี้แสดงว่าถ้าคิดว่าอนาคตผู้ใช้บริการจะเยอะขึ้น ควรตั้ง SYSTEM ให้มียอดสูงๆไว้
- ถ้ากรณีที่มีผู้ใช้มากจริงๆแล้วทะลุ SYSTEM มันจะปรับอย่างไรในอนาคตครับเพื่อไม่ให้กระทบกับ SYSTEM ที่เคยตั้งไว้ตอนแรก หรือเพิ่มได้เลย
---------------------------------------
ผมสงสัยว่า
อ้างถึง
พวกรายการเดียว ข้ามไป
พวกหลายรายการ ตรวจสอบว่า Hash transaction ID ซ้ำกันหรือไม่
ถ้าซ้ำรายการไหน ก็มาทำ algorithm ปรับค่าแสดงผลให้ admin ทราบอีกที  แล้วก็ปรับค่า Balance ใหม่
ตอนนี้ Balance เมื่อวาน ก็จะเท่ากับวันนี้แล้ว

อันนี้มันจะซ้ำอย่างไรหรอครับ ในเมื่อเราต้องเก็บ Hash transaction ID ไว้กรณีผู้โอนและผู้รับต้องระบุ Hash transaction ID ของผู้โอนไว้ ทั้งสองที่ อย่างงี้มันจะซ้ำกันนิครับหรือผมเข้าใจผิด คือที่ผมเข้าใจก็คือ เอาไว้เช็คว่ามีเงินเกินมั้ยถ้ามีก็หาว่าใครที่ผิดปกติ แล้วให้ระบบทำการปรับให้ตรง
---------------------------------------
อันนี้เป็นภาพที่ผมสรุปจากที่ท่านแนะนำมานะครับ หากผมเข้าใจผิดส่วนใดฝากแนะนำด้วยนะครับ โดยเฉพาะส่วนของ hash ที่ท่านบอกนั้น ที่เอาผู้โอนมาใส่ของทั้งรับและส่ง ให้เหมือนกัน ส่วนคนที่ฝากหรอถอนปกติไม่ได้โอนให้ใคร จำเป็นต้องใส่ Hash transaction ID ไหมครับ
(http://www.mediafire.com/convkey/5662/6lwu5129xysrn41zg.jpg)
---------------------------------------
อีกคำถามครับ เคยพบว่าในส่วนของ transaction โดนแก้ไขไหมครับ ถ้าโดนแก้ทั้งสองที่มีโอกาสแค่ไหน แล้วท่านรับมืออย่างไร

 :P

ผมต้องขอขอบคุณสำหรับคำแนะนำอีกรอบนะครับ และผมต้องขออภัยที่ต้องถามเยอะๆจนบางครั้งอาจจะดูเยอะเกินไป แต่เพื่อให้เคลียที่สุดในฐานะผู้พัฒนาก็เลยคิดว่าถามให้เคลียไปเลย จะได้ไม่ค้างคา แล้วพัฒนากับต่อยอดได้ไม่ติดขัด
 :-[


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: kingofdollars ที่ 30 มิถุนายน 2016, 08:07:20
พอดีผมไม่ได้เล่น Windows เลยไม่มี Exel ให้ทำ  เอางี้นะครับ ผมจะลองทำหัว ตารางให้ คร่าวๆ  พร้อม ข้อมูล


Table  USer

ID , NAME , BALANCE, INFO (Balance HASH), BALANCE2, INFO2 (Balance HASH), Register Date, STATUS, etc

1 : SYSTEM : 997,000 : XX34HASK2KXD : 1,000,000 :5OL9XHSDS : 2016-06-20 : 1
2 : A : 1000 : 5Ks9zLKDkd : 0 : SKSIKSF3343S :2016-06-28 : 1
3 : B : 2000 : XISLSsJSxXId : 0 : DKXODSLD : 2016-06-29 : 1

ใช้ชื่อ Field ของ Hash balance ให้เป็นชื่อที่เดาไม่ได้ เขาจะได้ไม่รู้ว่าอะไร
HASH INFO เอา UID + BALANCE + Register Date + Salt เป็นต้น
HASH INFO2 เอา UID + BLANCE2 + Register Date + Salt เป็นต้น   <---- yesterday balance


(A) Table Transaction แบบรวม แต่เวลาจะเอารายการของคนรับมาแสดง จะ Query ยากนิดนึง

ID, UID_Send, UID_Receive,  AMOUNT , HASH , DATE .....
1001 : 1 : 2 :  1,000 :  ASKDISD####$SDS : 2016-06-30
1002  : 1 : 3 : 2,000 : SKDFDISKD : 2016-06-30

(B) Table Transaction แบบแยก  แสดงรายการใคร ก็ query เฉพาะ User นั้นๆ

ID , UID , RID, XID . AMOUNT SEND, AMOUNT RECEIVE , HASH , XHASH , DATE ...
1001 : 1 : 2 : 1002 : 1,000 : 0 : DFDKFDSOSd : OSKX#S : 2016-06-30
1002 : 2 : 1 : 1001 : 0 : 1,000 : SKDIEX#SDK :OSKX#S :2016-06-30
1003 : 1 : 3 : 1004 : 2,000 : 0 : SKDI#DSDK : PLXI#SD : 2016-06-30
1004 : 3 : 1 : 1003 : 0 : 2,000 : SDK#SDDdk : PLXI#SD : 2016-06-30

HASH ธรรมดา เอาไว้ตรวจสอบ ยอดเงิน โอนให้ใครเมื่อไหร่ อย่าลืมใส่เกลือ
XHASH เอาไว้จับคู่ เอา HASH ตะกี้มาใส่อะไรเพิ่ม เช่น + UID Send + UID Receive + เกลือ



แบบหลังจะเห็นว่า ที่ ID 1001 เรารู้ได้อย่างไรถึง ID ล่วงหน้า ความจริงก็ Autorun เรารู้อยู่แล้วว่าเป็น ID อะไร แต่อย่างผมกันเหนียว ผมเก็บ
Transaction  ID เอาไว้ได้ เพราะต้องเอาไว้ลง row ใหม่อยู่แล้ว แล้วค่อยกลับไปอัพเดท row ที่แล้ว เพราะไม่แน่ว่า สองรายการเข้ามาพร้อมกัน คือการสร้าง row โอนออกพร้อมกัน row ฝั่งรับ อาจจะไม่ได้ run ลำดับนะครับ ต้องเก็บ id เอาไว้ก่อนแล้วค่อย update ทีหลัง

จินตนาการลำดับการโอนของ user ว่ากลายเป็น 1 -> 2, 1 -> 3 , 3 -> 1 , 2 -> 1 ก็เป็นได้ หวังว่าคงเข้าใจนะครับไม่งั้นการ อ้างอิงมั่วแน่

แบบนี้เวลาเราแสดงประวัติการโอนของ USER ID 1  เรา query ของ UID =1 เราก็เห็นว่าใครโอนให้ใคร เท่าไหร่ ได้เลย admin ก็ dril down จับคู่ได้ทันทีว่าคู่ไหน

____________
คราวนี้ เพื่อให้ระบบแม่นยำ คุณก็ทำทั้ง 2 Table แต่ Table แบบแรก ไม่เอาไปคำนวน Balance เอาไว้เก็บอ้างอิงเฉพาะแต่ละวัน ครบ  1 เดือนลบที

พอเจอว่า ยอดเงินมีปัญหา รวมของทุก USer แล้วไม่เท่าเดิม คุณก็ไปเอาข้อมูลแบบง่ายมา (A) มาประมวลผลแบบยาวใหม่ (B)

_____

ปัญหาคือ ใน table (A) มันอาจจะเข้ามา ซ้ำๆ ด้วยการกดรัวๆ ของ User ได้  เราต้องดักด้วย Javascript ในการ submit คือ ถ้ากด send แล้วต้อง Disable ปุ่มกด แล้วส่งข้อมูลไปหา server

ฝั่ง server ต้องตรวจสอบเวลาว่า หากในช่วง 1 นาทีที่ผ่านมา ใน Table(A) มีการส่งคำสั่งจาก User เดียวกันเข้ามา ก็ให้ถามให้แน่ใจก่อนว่า จะทำซ้ำหรือไม่ ดังนั้นถ้าเขาเปิดสองหน้าเพื่อโอนไป user เดียวกัน อีกหน้าก็จะมีการถาม ให้ยืนยันอีกที

______

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

หน้าที่เราก็แค่เช็ค XHASH ว่ามันมีเกิน 2 row หรือไม่ crone ตัวนี้ ทำงานหนักหน่อย ในแต่ละวันที่ประมวลผลตรวจสอบ

___

อย่าลืมว่า SYSTEM ก็เป็น user account อันหนึ่ง คุณต้องใส่ password ยาวๆเอาไว้
ระบบที่ผมเคยทำ มีการหักค่าธรรมเนียมด้วย  ก็จะมี SYSTEM account สำหรับค่าธรรมเนียมด้วย
เวลามีโอนเข้าโอนออก ก็จะหักจาก user account -> fees account ซึ่งเป็นของระบบ
เวลาเราถอนเงินกำไรออก ก็ลดค่าใน fee account ลง แต่ทุกอย่างก็รวมได้เท่าเดิม


คราวนี้การบริหารจัดการคือ

System account คือเงินในระบบ จะต้องเท่ากับเงินที่ท่านมีอยู่ในบัญชีธนาคาร (เนื่องจากผมทำ payment processor)
พอใครโอนเงินสดให้คุณ  เช็คเงินแล้ว ก็ไปอับเดทเงินในระบบ  แบบนี้คุณต้องทำ ตารางมาต่างหาก เพื่อดูข้อมูลการรับจ่ายเงิน  ยุ่งยาก


ผมใช้วิธี ตั้งเงินในระบบไว้ 1 ล้าน  ใครโอนเงินมา ผมก็โอนจาก System  เข้าไป  เราแค่เขียนโค้ดว่า ถ้ามาจาก User ID =1 (system) ก็ระบุชื่อว่า เติมเงิน   ถ้าถอนเงิน  User ก็โอนเข้า System

จะเห็นว่า ดูที่ยอดเงินของ system ถ้าเหลือ 900,000 แสดงว่ามีเงินในระบบอยู่ 100,000 บาท ตรงกับเงินในบัญชีธนาคารไหม

คราวนี้การแก้เงิน 1 ล้าน ให้เป็น 10 ล้าน ก็ทำได้ทันที  ตัวแปร คือ total money ซึ่งฝังอยู่ในโค้ดเลย แล้ว encrypt ด้วย ioncube แม้แต่เจ้าของ host ก็แก้ไม่ได้

พนักงานในบริษัท ก็แก้ไม่ได้ ใครไปยุ่งใน DB แล้วทำให้ hash เพี้ยน ก็หาตัวการได้เลย halt ระบบเอาไว้ได้ก่อน

อย่าลืม Salt แต่ละอันก็ encrypt ไว้หมด ในไฟล์ config แนะนำ ioncube มากกว่า zend ครับ


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: kingofdollars ที่ 30 มิถุนายน 2016, 08:09:52
ส่วน table crone ต้องทำครับ ไม่งั้น run crone แล้วมั่ว


ID , DATE , LAST TR ID ,status
1001: 2016-06-29 : 29393 , 0

ก่อน run ทุกครั้ง ตรวจสอบว่า run หรือยัง ไม่งั้นมั่วแน่นอน


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nscyber ที่ 30 มิถุนายน 2016, 10:57:16
ความรู้เลยครับ


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: MapTwoZa ที่ 30 มิถุนายน 2016, 11:02:50
เล่นระบบบัญชีคู่เลยหรอ

ถ้าจะทำบัญชีคู่จริง จขกท ต้องไปศึกษาระบบบัญชีคู่ด้วยนะ มันซับซ้อนนิดนึง


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nat-ns ที่ 30 มิถุนายน 2016, 11:30:52
ขอบคุณครับพอเห็นภาพเลย  :-[

ผมสงสัยตรง
อ้างถึง
คราวนี้การแก้เงิน 1 ล้าน ให้เป็น 10 ล้าน ก็ทำได้ทันที  ตัวแปร คือ total money ซึ่งฝังอยู่ในโค้ดเลย
ในเมื่อผมแก้ในสคริป php ผมก็ต้องเข้าไปแก้ใน Table  USer ID 1 ให้ BALANCE เพิ่มจากที่เหลือเข้าไปอีก 10 ล้านเช่น ปัจจุบันเหลืออยู่ 997,000 ก็เพิ่มไปอีก 997,000+10,000,000
ใช่ไหมครับ คือแก้ทั้งฐานข้อมูลและฝั่งสคริปที่ไว้ตรวจสอบ
-----------
ถ้า XHASH มีมากกว่าหนึ่งนี่ก็คือมีการเปลี่ยนแปลงข้อมูลก็จับ A มาทำ B ใหม่ และปรับค่า BALANCE ใน TABLE USER ใหม่ ผมเข้าใจถูกไหมครับ
-----------

ส่วน table crone ต้องทำครับ ไม่งั้น run crone แล้วมั่ว


ID , DATE , LAST TR ID ,status
1001: 2016-06-29 : 29393 , 0

ก่อน run ทุกครั้ง ตรวจสอบว่า run หรือยัง ไม่งั้นมั่วแน่นอน

อันนี้คือของรายการต่อวันใช่ไหมครับ กรณีที่ เมื่อวานทำไปแล้วก็เก็บประวัติไว้ เพื่อจะได้ไม่ต้องย้อนกลับไปคำนวณของเมื่อวานอีก อย่างเช่น TR ID ของวันเก่าที่ status = 1(ทั้งหมด) จะมี TR ID=1001-1005 พอเราจะตรวจเชควันนี้ก็เริ่มที่ 1005-N ไปเลย  :wanwan012:


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nat-ns ที่ 30 มิถุนายน 2016, 12:07:03
เล่นระบบบัญชีคู่เลยหรอ

ถ้าจะทำบัญชีคู่จริง จขกท ต้องไปศึกษาระบบบัญชีคู่ด้วยนะ มันซับซ้อนนิดนึง

ไม่ต้องถึงขนาดนั้นก็ได้ครับ จากหลักการข้างบนก็ใช้ได้แล้วครับ แต่ก็ฝากแนะนำด้วยครับ 555 เผื่อนำมาประยุกต์กันได้  :wanwan012:


หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: kingofdollars ที่ 30 มิถุนายน 2016, 13:59:24
ขอบคุณครับพอเห็นภาพเลย  :-[

ผมสงสัยตรง
อ้างถึง
คราวนี้การแก้เงิน 1 ล้าน ให้เป็น 10 ล้าน ก็ทำได้ทันที  ตัวแปร คือ total money ซึ่งฝังอยู่ในโค้ดเลย
ในเมื่อผมแก้ในสคริป php ผมก็ต้องเข้าไปแก้ใน Table  USer ID 1 ให้ BALANCE เพิ่มจากที่เหลือเข้าไปอีก 10 ล้านเช่น ปัจจุบันเหลืออยู่ 997,000 ก็เพิ่มไปอีก 997,000+10,000,000
ใช่ไหมครับ คือแก้ทั้งฐานข้อมูลและฝั่งสคริปที่ไว้ตรวจสอบ


นานๆ คงจะทำซักทีตรงนี้  นั่นคือคุณเปลี่ยนตัวแปรใน config ไฟล์  แล้ว แก้ไขข้อมูลใน DB และ HASH ให้ถูกต้องครับ

ทำ script เตรียมไว้เลยครับ บวกเงินทีละ 1,000,000 หรือ ลบทีละ 1,000,000 ในฐานข้อมูล พร้อม HASH ทำเสร็จ ลบไฟล์นี้ทิ้ง (อย่าลืมทำ password hard-coded ไว้เลย เผื่อลืมลบไฟล์)  ได้ยอดที่ต้องการแล้วก็ไปแก้ใน config เอาไว้เปรียบเทียบ


-----------
ถ้า XHASH มีมากกว่าหนึ่งนี่ก็คือมีการเปลี่ยนแปลงข้อมูลก็จับ A มาทำ B ใหม่ และปรับค่า BALANCE ใน TABLE USER ใหม่ ผมเข้าใจถูกไหมครับ

ถ้ามีเกิน 1 คู่เมื่อไหร่ แสดงว่ามีข้อผิดพลาดเกิดขึ้น ก็ต้อง run cron เริ่มจาก นำ balance เก่าแต่ละรายมาคิด แล้วดึงข้อมูลจาก Table A มาคำนวนใหม่ทีละรายการ เพื่อให้ได้ Table B อันใหม่  บางคนเลยอาจจะมียอดเงินติดลบ แต่คิดว่าคงเกิดขึ้นนานๆที
-----------

ส่วน table crone ต้องทำครับ ไม่งั้น run crone แล้วมั่ว


ID , DATE , LAST TR ID ,status
1001: 2016-06-29 : 29393 , 0

ก่อน run ทุกครั้ง ตรวจสอบว่า run หรือยัง ไม่งั้นมั่วแน่นอน

อันนี้คือของรายการต่อวันใช่ไหมครับ กรณีที่ เมื่อวานทำไปแล้วก็เก็บประวัติไว้ เพื่อจะได้ไม่ต้องย้อนกลับไปคำนวณของเมื่อวานอีก อย่างเช่น TR ID ของวันเก่าที่ status = 1(ทั้งหมด) จะมี TR ID=1001-1005 พอเราจะตรวจเชควันนี้ก็เริ่มที่ 1005-N ไปเลย  :wanwan012:

ถ้ามีปัญหา เราจะได้รู้ว่า ID สุดท้ายของ Table B ที่ไม่มีปัญหาคืออะไร
Algo คือ
1 ตรวจสอบว่า run cron หรือยัง ถ้า run แล้วก็จบ
2 ถ้ายังไม่ run ก็เริ่มรัน พร้อมบันทึกวันที่วันนี้ลงไป
3 หา Hash ที่เกิน 1 คู่ ถ้าเกิน ลบข้อมูลใน table B ทิ้งตั้งแต่ 1006 เป็นต้นไป
4 ถ้า 3 ไม่มีปัญหา เช็คยอดเงินรวม  ถ้ามีปัญหา ก็ทำข้อ 3
5 เอา ID สุดท้ายของ table B ใส่กลับเข้ามา เป็นอันจบ



หัวข้อ: Re: ท่านใดเคยเขียนเว็บที่มีการอัพเดทข้อมูลบน SQLถี่ๆเช่นเว็บเกี่ยวกับเงินบ้างครับ +1
เริ่มหัวข้อโดย: nat-ns ที่ 01 กรกฎาคม 2016, 02:49:46
ขอบคุณครับพอเห็นภาพเลย  :-[

ผมสงสัยตรง
อ้างถึง
คราวนี้การแก้เงิน 1 ล้าน ให้เป็น 10 ล้าน ก็ทำได้ทันที  ตัวแปร คือ total money ซึ่งฝังอยู่ในโค้ดเลย
ในเมื่อผมแก้ในสคริป php ผมก็ต้องเข้าไปแก้ใน Table  USer ID 1 ให้ BALANCE เพิ่มจากที่เหลือเข้าไปอีก 10 ล้านเช่น ปัจจุบันเหลืออยู่ 997,000 ก็เพิ่มไปอีก 997,000+10,000,000
ใช่ไหมครับ คือแก้ทั้งฐานข้อมูลและฝั่งสคริปที่ไว้ตรวจสอบ


นานๆ คงจะทำซักทีตรงนี้  นั่นคือคุณเปลี่ยนตัวแปรใน config ไฟล์  แล้ว แก้ไขข้อมูลใน DB และ HASH ให้ถูกต้องครับ

ทำ script เตรียมไว้เลยครับ บวกเงินทีละ 1,000,000 หรือ ลบทีละ 1,000,000 ในฐานข้อมูล พร้อม HASH ทำเสร็จ ลบไฟล์นี้ทิ้ง (อย่าลืมทำ password hard-coded ไว้เลย เผื่อลืมลบไฟล์)  ได้ยอดที่ต้องการแล้วก็ไปแก้ใน config เอาไว้เปรียบเทียบ


-----------
ถ้า XHASH มีมากกว่าหนึ่งนี่ก็คือมีการเปลี่ยนแปลงข้อมูลก็จับ A มาทำ B ใหม่ และปรับค่า BALANCE ใน TABLE USER ใหม่ ผมเข้าใจถูกไหมครับ

ถ้ามีเกิน 1 คู่เมื่อไหร่ แสดงว่ามีข้อผิดพลาดเกิดขึ้น ก็ต้อง run cron เริ่มจาก นำ balance เก่าแต่ละรายมาคิด แล้วดึงข้อมูลจาก Table A มาคำนวนใหม่ทีละรายการ เพื่อให้ได้ Table B อันใหม่  บางคนเลยอาจจะมียอดเงินติดลบ แต่คิดว่าคงเกิดขึ้นนานๆที
-----------

ส่วน table crone ต้องทำครับ ไม่งั้น run crone แล้วมั่ว


ID , DATE , LAST TR ID ,status
1001: 2016-06-29 : 29393 , 0

ก่อน run ทุกครั้ง ตรวจสอบว่า run หรือยัง ไม่งั้นมั่วแน่นอน

อันนี้คือของรายการต่อวันใช่ไหมครับ กรณีที่ เมื่อวานทำไปแล้วก็เก็บประวัติไว้ เพื่อจะได้ไม่ต้องย้อนกลับไปคำนวณของเมื่อวานอีก อย่างเช่น TR ID ของวันเก่าที่ status = 1(ทั้งหมด) จะมี TR ID=1001-1005 พอเราจะตรวจเชควันนี้ก็เริ่มที่ 1005-N ไปเลย  :wanwan012:

ถ้ามีปัญหา เราจะได้รู้ว่า ID สุดท้ายของ Table B ที่ไม่มีปัญหาคืออะไร
Algo คือ
1 ตรวจสอบว่า run cron หรือยัง ถ้า run แล้วก็จบ
2 ถ้ายังไม่ run ก็เริ่มรัน พร้อมบันทึกวันที่วันนี้ลงไป
3 หา Hash ที่เกิน 1 คู่ ถ้าเกิน ลบข้อมูลใน table B ทิ้งตั้งแต่ 1006 เป็นต้นไป
4 ถ้า 3 ไม่มีปัญหา เช็คยอดเงินรวม  ถ้ามีปัญหา ก็ทำข้อ 3
5 เอา ID สุดท้ายของ table B ใส่กลับเข้ามา เป็นอันจบ



ขอบคุณมากครับ  :wanwan019:  :wanwan017:  :wanwan017:  :wanwan017:  :wanwan017: