ThaiSEOBoard.com

พัฒนาเว็บไซต์ => Programming => ข้อความที่เริ่มโดย: ttong ที่ 06 ตุลาคม 2017, 20:18:47



หัวข้อ: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: ttong ที่ 06 ตุลาคม 2017, 20:18:47
สอบถามเรื่อง MySQL ครับ
ผมมีตารางที่เก็บข้อมูลไว้ประมาณนี้

tableB
-------------------------------------------------------
id       key        value        refid
-------------------------------------------------------
1     Type     Type1     1
2     Name     Somchai     1
3     Show     Y     1
4     Type     Type2     2
5     Name     Somying     2
6     Show     Y     2
7     Type     Type2     3
8     Name     Somjai     3
9     Show     Y     3
10     Type     Type1     4
11     Name     Somsak     4
12     Show     N     4
13     Type     Type1     5
14     Name     Somporn     5
15     Show     Y     5
-------------------------------------------------------

ผมต้องการดึงข้อมูลออกมาโดยมีเงื่อนไขว่า
Type ต้องเท่ากับ Type1 และ Show ต้องเท่ากับ Y และ Group ด้วย RefID
ซึ่งจะได้ข้อมูลออกมา เพียง RefID ที่ 1 และ 5 (ตัวอักษรสีแดง)

โค๊ด:
SELECT * from tableB WHERE (key = 'Type' AND value = 'Type1') AND (key = 'Show' AND value = 'Y');
ผมลองใช้คำสั่งด้านบน แต่ไม่ได้ผลลัพธ์อะไรออกมา

รบกวนขอคำแนะนำด้วยครับ
ขอบคุณครับ


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: gubaaball ที่ 06 ตุลาคม 2017, 20:44:36
เปลี่ยน AND ตรงกลางเป็น OR ก็น่าจะได้น่ะครับ (AND คือและ จะต้องจริงทั้งซ้ายและขวาถึงจะได้ครับ ในกรณีท่านเข้าใจว่าน่าจะซ้ายหรือขวามากกว่า)


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: thaisew ที่ 06 ตุลาคม 2017, 20:54:45
เช็ค Reserved Words ก่อนครับ ไม่งั้น query ยังไงก็ไม่ออก  :wanwan009:


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: dekdoo ที่ 06 ตุลาคม 2017, 21:01:59
ใช้ OR ตามที่ข้างบนบอก จากนั้นก็ ORDER BY refid


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: infamous ที่ 06 ตุลาคม 2017, 21:38:56
ผมว่าเปลี่ยนโครงสร้างของ columns ใหม่จะดีกว่าหรือเปล่าครับ เพราะผมดูแล้ว subset ตัวเดียวจะมี 3 แถว คือ type,name,show
ท่านลองจินตนาการดูนะครับว่า ถ้าข้อมูลมีสัก 10,000 subset มันจะมีกี่ rows 10000*3 นั่นเอง

ตัวอย่าง columns ใหม่ที่ควรจะเป็น เพื่อทำให้คำสั่ง query ง่ายขึ้น

-----------------------
id|type|name|show|refid
-----------------------
1|type1|Somchai|Y|1
2|type2|Somying|Y|2
-----------------------
so on...

จากนั้นก็เล่นง่ายๆเลยครับ

select * from db where type='{type}' and show='Y';


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: ttong ที่ 06 ตุลาคม 2017, 23:11:31
เปลี่ยน AND ตรงกลางเป็น OR ก็น่าจะได้น่ะครับ (AND คือและ จะต้องจริงทั้งซ้ายและขวาถึงจะได้ครับ ในกรณีท่านเข้าใจว่าน่าจะซ้ายหรือขวามากกว่า)
ใช้ OR ตามที่ข้างบนบอก จากนั้นก็ ORDER BY refid

หากใช้ OR ตรงกลาง
จะได้ข้อมูลของแถวที่ 6, 9, 10 มาด้วยครับ

จริงๆ แล้วผมต้องการให้เงื่อนไขตรงทั้ง ซ้ายและขวา ครับ


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: ttong ที่ 06 ตุลาคม 2017, 23:16:40
ผมว่าเปลี่ยนโครงสร้างของ columns ใหม่จะดีกว่าหรือเปล่าครับ เพราะผมดูแล้ว subset ตัวเดียวจะมี 3 แถว คือ type,name,show
ท่านลองจินตนาการดูนะครับว่า ถ้าข้อมูลมีสัก 10,000 subset มันจะมีกี่ rows 10000*3 นั่นเอง

ตัวอย่าง columns ใหม่ที่ควรจะเป็น เพื่อทำให้คำสั่ง query ง่ายขึ้น

-----------------------
id|type|name|show|refid
-----------------------
1|type1|Somchai|Y|1
2|type2|Somying|Y|2
-----------------------
so on...

จากนั้นก็เล่นง่ายๆเลยครับ

select * from db where type='{type}' and show='Y';

ระบบนี้ข้อมูลจะมีไม่เยอะครับ
ไม่น่าถึง 1000 แถว

ตอนที่ออกแบบ ฐานข้อมูล หวังว่าจะให้มันยึดหยุ่นครับ
แต่พอมาเจอ เงื่อนไขแบบนี้ ทำให้ตันเลย

หากหาทางไม่ได้จริงๆ คงต้องทำแบบท่านว่า
แต่ต้องรื้อใหม่เกือบหมด  :wanwan031:


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: sputtaro ที่ 07 ตุลาคม 2017, 10:55:52
เป็นตารางที่ออกแบบไว้ไม่ดีนัก

อาจลอง select refid where value=Type1 and value=Y (เพื่อให้ได้ ตัวอ้างอิงคือ refid)
จากนั้นค่อย select ครั้งที่สอง โดย
select value where refid=...

นี่เป็นแนวคิดคร่าวๆนะครับ (คุณอาจใช้ select in select แทนก็ได้ เพื่อให้มีแค่ query เดียว)

ส่วนทางแก้ปัญหาที่น่าจะดีกว่าตามแนวคิดผมก็คือ
ทำตามที่ท่าน infamous แนะนำนั่นแหละครับ

ผมลองคิดดูเล่นๆ จะ insert into newtable from oldtable (select ....
มันยังยากเลย แต่ควรแก้ไขตั้งแต่เนิ่นๆ เพราะยิ่งมีข้อมูลมาก
ตารางของคุณก็จะใช้เวลานานมากขึ้นในการค้นหา
รีบแก้เสียแต่ตอนนี้ยังดีกว่าครับ



หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: ttong ที่ 08 ตุลาคม 2017, 13:36:32
ที่ผมออกแบบฐานข้อมูลแบบนี้ เพราะ

ปกติแล้ว ผมมักจะออกแบบฐานข้อมูล ดังนี้
หากทำระบบสินค้า และระบบข่าวสาร มีอยู่ 3 ตาราง คือ
- Table Category เก็บข้อมูลหมวดหมู่สินค้า คือ รหัส, ชื่อ
- Table Product เก็บข้อมูลสินค้า คือ รหัส, ชื่อ, ราคา, รหัสหมวดหมู่
- Table News เก็บข้อมูลข่าวสาร คือ รหัส, ชื่อ, รายละเอียด

---------------------------------
Table Category
---------------------------------
ID|Name

---------------------------------
Table Product
---------------------------------
ID|Name|Price|CategoryID

---------------------------------
Table News
---------------------------------
ID|Name|Detail

วันนึง อาจจะมีบางเว็บไซต์ที่ต้องการรายละเอียดสินค้ามากกว่าเดิม เช่น
ต้องการเก็บ ส่วนลด และ รายละเอียดสินค้า เพิ่ม
ผมก็ต้องมาแก้ตาราง Table Product โดยเพิ่มดังนี้

---------------------------------
Table Product
---------------------------------
ID|Name|Price|Discount|Detail|CategoryID

และเมื่อไปเจอเว็บไซต์อื่นๆ อาจจะไม่ต้องการส่วนลด แต่ต้องการรายละเอียดอื่น
ผมก็ต้องกลับมาแก้ตาราง Table Product อีก



ผมจึงลองออกแบบฐานข้อมูลใหม่ ซึ่งต้องการให้ยืดหยุ่น เพื่อรองรับสถานการณ์แบบนี้
โดยที่ เก็บชื่อฟิลด์ ลงตารางด้วยเลย จึงเป็นดังนี้
- Table Category เก็บข้อมูลหมวดหมู่สินค้า คือ รหัส, ชื่อ
- Table Content เก็บข้อมูลของระบบงาน คือ รหัส, ประเภทระบบงาน
- Table Product เก็บรายละเอียดของสินค้า คือ รหัส, ฟิลด์, ค่า, รหัสระบบงาน
- Table News เก็บรายละเอียดของข่าวสาร คือ รหัส, ฟิลด์, ค่า, รหัสระบบงาน

---------------------------------
Table Category
---------------------------------
ID|Name

---------------------------------
Table Content
---------------------------------
ID|Type

---------------------------------
Table Product
---------------------------------
ID|Field|Value|ContentID

---------------------------------
Table News
---------------------------------
ID|Field|Value|ContentID

หากระบบสินค้าต้องการเก็บข้อมูล
รหัส, ชื่อ, ราคา, รหัสหมวดหมู่ ก็จะเป็นดังนี้

---------------------------------
Table Category
---------------------------------
ID|Name
---------------------------------
1|เครื่องใช้ในสำนักงาน

---------------------------------
Table Content
---------------------------------
ID|Type
---------------------------------
1|product
2|news
3|news
4|product

---------------------------------
Table Product
---------------------------------
ID|Field|Value|ContentID
---------------------------------
1|Name|ดินสอ|1
2|Price|10|1
3|Category|1|1
4|Name|ปากกา|4
5|Price|5|4
6|Category|1|4

และวันนึงหากต้องการเก็บ ส่วนลด และ รายละเอียดสินค้า เพิ่ม
ผมก็ไม่จำเป็นต้องมาแก้โครงสร้างของฐานข้อมูล
ผมเพียงเพิ่มข้อมูลฟิลด์ที่ต้องการเพิ่มลงในตาราง Table Product เช่น

---------------------------------
Table Product
---------------------------------
ID|Field|Value|ContentID
---------------------------------
1|Name|ดินสอ|1
2|Price|10|1
3|Discount|2|1
4|Detail|ดินสอไม้สำหรับวาดรูป|1
5|Category|1|1
6|Name|ปากกา|4
7|Price|15|4
8|Discount|5|4
9|Detail|ปากกาสีแดง|4
10|Category|1|4



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

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


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: gubaaball ที่ 08 ตุลาคม 2017, 15:49:12
เปลี่ยน AND ตรงกลางเป็น OR ก็น่าจะได้น่ะครับ (AND คือและ จะต้องจริงทั้งซ้ายและขวาถึงจะได้ครับ ในกรณีท่านเข้าใจว่าน่าจะซ้ายหรือขวามากกว่า)
ใช้ OR ตามที่ข้างบนบอก จากนั้นก็ ORDER BY refid

หากใช้ OR ตรงกลาง
จะได้ข้อมูลของแถวที่ 6, 9, 10 มาด้วยครับ

จริงๆ แล้วผมต้องการให้เงื่อนไขตรงทั้ง ซ้ายและขวา ครับ
ตามเงื่อนไขที่ท่านอยากได้ใส่ OR ตรงกลางน่ะแหละครับ แล้วที่มี 6,9,10 มาด้วยเพราะท่านไม่ได้ where refid = '1' OR refid = '5' ครับ โค้ดเดิมของท่านมันจะไม่มีข้อมูลออกมาแน่นอนครับ เพราะมันจะออกมาได้ก็ต่อเมื่อ key = 'Type' AND key = 'Show' ลองเช็คเงื่อนไข OR กับ AND ให้ดีครับ โค้ดผมไม่ได้เทสน่ะครับ ลองดูอีกที

โค๊ด:
SELECT * from tableB WHERE ((key = 'Type' AND value = 'Type1') OR (key = 'Show' AND value = 'Y')) AND (refid = '1' OR refid = '5');


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: gubaaball ที่ 08 ตุลาคม 2017, 16:00:34
แต่ถ้าอ่านตามโครงสร้างฐานข้อมูลท่านบอกแล้วหากใช้ AND ref= ต่อไม่ได้ ก็น่าจะต้องออกแบบฐานข้อมูลใหม่ครับ เพราะฟิลด์ที่ท่านใช้ where อยู่มันมีข้อมูลที่ซ้ำกันกับแถวที่ไม่อยากได้ ทางแก้คือเพิ่มอีกฟิลด์เพื่อแยกสองอันนี้แล้วเพิ่มเข้าไปในเงื่อนไข where ครับ


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: infamous ที่ 08 ตุลาคม 2017, 16:14:29
ท่านเคยสังเกตุหรือเปล่าว่า ตารางสินค้าของท่านมันกระดิกในเรื่องออปชั่นได้(อ้างอิงจากข้อมูลท่าน)
พอออปชั่นเปลี่ยนท่านจะต้องมาแก้ schema ของ table ใหม่ทุกครั้งไปหรือครับ
สำหรับผมแล้ว มันไม่ใช่ครับ แนวคิดของท่านมันไม่ยืดหยุ่นครับ เชื่อผม เพราะผมรู้ว่าในอนาคตท่านจะต้องเจอกับปัญหาอะไรบ้าง ถ้าท่านยังใช้ schema ในลักษณะนี้

ผมเป็นคนออกแบบระบบ E-commerce ให้ลูกค้ามาหลายเจ้า และเชื่อว่าออปชั่นมากกว่าของท่านอย่างแน่นอน
ดังนั้น การออกแบบ Table ใน DB ที่ดีคือ ครอบคลุมให้มากที่สุด ครั้งเดียว เอาให้จบเลย หรืออย่างน้อยให้เกิน 80%
ให้ศึกษาพวก Relationship เพราะมันจะทำให้ท่านทำงานง่ายขึ้น Query เร็วขึ้นด้วย

ก่อนออกแบบ เราควรมีการวางแผนและเขียนพวก ER ไดอะแกรม ของ TB ทั้งหมดและมองหาความสัมพันธ์ที่คิดว่าน่าจะได้ใช้และในอนาคตข้างหน้า(อันนี้สำคัญมากครับ)

อันนี้ตัวอย่าง schema แบบง่ายๆที่ผมพอจะนึกได้ตอนสมัยเรียน(เมื่อสัก 10ปีที่แล้ว)

product_category(master table)

-cat_id
-cat_parent_id(parent&child supported)
-cat_name
-cat_desc
-cat_slug(SEO)
-cat_meta_title(SEO)
-cat_meta_desc(SEO)
-cat_tag
-cat_status
-cat_date_added
-cat_date_modified

cat_to_product(slave table)

-cat_to_product_id
-cat_id
-product_id

product(master table)

-p_id
-p_name
-p_slug(SEO)
-p_meta_title(SEO)
-p_meta_desc(SEO)
-p_tag(SEO)
-p_desc
-p_price
-p_special
-p_thumb
-p_status
-p_date_added
-p_date_modified

product_option(slave table)

-option_id
-p_id
-option_key
-option_value

ปล เมื่อท่านต้องการเปลี่ยนออปชั่นสินค้า ท่านก็แค่ระบุ option_key และ option_value ให้กับ product รายการนั้นโดยใช้ p_id มา JOIN
ทีนี้ระบบของท่านก็ฉลาดและยืดหยุ่นขึ้น โดยที่ไม่ต้องมาแก้ schema ของ TB แล้วครับ

แต่ถ้าท่านไม่อยากแก้ไขเพราะชินกับการออกแบบในลักษณะนี้ ลองดูในเรื่อง Sub-Queryหรือพวก Nested Query ครับ จบปัญหานี้ได้แน่นอน เพราะผมลองทดสอบตามโครงสร้างเดิมของท่านดูแล้ว (แต่ไม่แนะนำ)


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: sputtaro ที่ 08 ตุลาคม 2017, 17:00:46
โครงสร้างตารางแบบที่ จขกท.ใช้อยู่ ถ้าพูดตามตรง ใครๆก็ใช้แบบนี้กันทั้งนั้นครับ
ยิ่งฐานข้อมูลมีความสลับซับซ้อนก็ยิ่งต้องใช้
เพราะมันช่วยตัดตอนการค้นหาข้อมูลที่อยู่ในตารางอื่นๆได้ดี

เช่น
ตารางพวก user log data
หรือ พวก Member Orders ซึ่งจะเก็บข้อมูลใบสั่งซื้อของลูกค้าไว้ทุกๆใบ และทุกๆคน
มันจะเก็บแค่ user_id orders_id total_of_order และอาจมีฟิล์ดเพิ่มอีกแค่ order_datetime
มีฟิล์ด orderid เป็น autoincrement
ส่วน user_id กับ orders_id เป็น relation ของ ตาราง Members กับ ตาราง Orders

ตารางนี้จะใช้ในการค้นหายอดขายในแต่ละช่วง เช่น รายวัน รายเดือน ...
รวมทั้งค้นหา ประวัติการสั่งซื้อของลูกค้าแต่ละคน

มันจึงเป็นตารางที่มีเร็คคอร์ดจำนวนมาก บางฐานข้อมูล มีอยู่หลายล้านเร็คคอร์ด เพราะต้องเก็บไว้หลายปี
(แน่นอนว่า มันขึ้นอยู่กับขนาดของร้านหรือเว็บด้วยครับ)

*****************************************************************************

ลองสังเกคุดูนะครับ
ตัวอย่างที่ท่าน infamous ยกมา เมื่อเทียบกับชองท่านจขกท. ก็คือ

product_option(slave table)
-option_id
-p_id
-option_key
-option_value

แต่สิ่งที่ต่างกันก็คือ ของจขกท. ต้องการ p_id เป็น output
ซึ่งมันจะสวนทางกับวัตถุประสงค์ที่แท้จริงของตารางประเภทนี้
นั่นก็คือ ใส่ input เป็น p_id แล้วจะได้ option_key, option_value ออกมา

เช่นเดียวกับตาราง Member Orders ที่ผมยกตัวอย่างด้านบน
เมื่อเราต้องการทราบว่า ลูกค้า id อะไร สั่งสินค้าอะไรไปบ้าง เราก็แค่
select ... where memberid=userid
หรือ
จะค้นหา ยอดสั่งซื้อ ในแต่ละช่วง ก็ไม่ยุ่งยาก ไม่ซับซ้อนมากมาย

ลองพิจารณาดูนะครับ

***********************************************

พิมพ์ผิดตรงไหนขออภัยด้วยนะครับ


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: ttong ที่ 08 ตุลาคม 2017, 19:32:47
มาถึงตอนนี้ ผมคิดว่าคงต้องออกแบบฐานข้อมูลใหม่
โดยจะลองใช้หลักของคุณ infamous ดูครับ

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

ขอบคุณทุกๆ ท่านมากครับ ที่สละเวลามาให้คำแนะนำ

:wanwan017: :wanwan017: :wanwan017:


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: imaim09 ที่ 17 ตุลาคม 2017, 19:34:35
SQL เคยเรียนมันยากมากเลยตอนเรียน :'( :'(


หัวข้อ: Re: ขอคำแนะนำเรื่องการดึงข้อมูลจาก MySQL
เริ่มหัวข้อโดย: aunyikar ที่ 17 ตุลาคม 2017, 20:07:01
ยากมากเลยค่ะ