Hi !!! ทุกคนนน วันนี้เราก็กลับมาอีกครั้งกับหัวข้อที่เราทิ้งไว้รอบที่แล้วกันนนนนั้นก็ คือออออออออออ คือออออออ Association หรือ Relation ของ SQL นั่นเองงงง และในครั้งนี้เราก็จะใช้ Schema ของ Database เดียวกันในรอบที่ผ่าน ๆ มากันนะครับ และใครที่เข้ามาอ่านครั้งแรกก็สามารถกลับไปอ่านบนความเก่า ๆ ได้ที่นี่ ( sequelize 101 ) และ ที่นี่ ( 5 function ที่เราได้ใช้แน่ๆใน sequelize ) โอเคเรามาเริ่มกันเลยยย
ประเภทของ Relations ถูกแบ่งออกเป็น 3 แบบได้แก่
1.ความสัมพันธ์แบบ One-to-One [1:1]
เป็นความสัมพันธ์แบบหนึ่งต่อหนี่ง เช่น คนหนึ่งคนสามารถมีบัตรประชาชนได้แค่ 1 ใบเท่านั้น ( ถ้าไม่ติดว่าเราทำหายอะนะ 5555 )
2.ความสัมพันธ์แบบ One-to-Many [1:N]
ความสัมพันธ์นี้เป็นความสัมพันธ์ที่เกิดขึ้นมากที่สุดในการสร้างฐานข้อมูล เป็นความสัมพันธ์ระหว่างหนึ่งสิ่งต่อหลาย ๆ สิ่ง เช่น ทีมฟุตบอล 1 ทีมสามารถมีนักฟุตบอลได้หลายคน
3.ความสัมพันธ์แบบ Many-to-Many [M:N]
เป็นความสัมพันธ์แบบหลายสิ่งต่อหลายสิ่ง เช่น 1 ข่าวสามารถทีได้หลายแท็ก และใน 1 แท็กก็มีได้หลายข่าว
แล้วในการที่เราจะสร้าง Relation ใน Sequelize เราจะสามารถสร้างได้โดยใช้ Association และ association ของ Sequelize จะแบ่งออกเป็น 4 แบบก็คือ
- HasOne association
- BelongsTo association
- HasMany association
- BelongsToMany association
โดยเราถ้าเราจะสร้าง 1:N relation เราก็จะใช้ HasMany คู่กับ BelongsTo โดยวิธีก็จะเป็นแบบ code ด้านล่างครับ
โดย db.team กับ db.player คือ model ที่เราสร้างไว้ในครั้งก่อน ๆ นะครับ
db.team.hasMany(
db.player,
{
foreignKey: { name: 'tid', field: 'tid' }, //<- เป็นการกำหนดว่าใช้ FK ชื่ออะไรเวลาเราเรียกฝช่งานให้เราใช้ name ที่เราตั้ง ในการใช้งานแนะครับ เผื่อเวลาที่เราเปลี่ยนชื่อFKใน database จะได้ไม่งง
}
);
db.player.belongsTo(db.team, { foreignKey: 'tid' });
จาก code ด้านบนจำทำการสร้าง FK ในตาราง player ให้เราโดยใช้ PK ของ team ( จริงๆเรามาสารถใช้ hasMay อย่างเดียวได้นะครับแต่เราจะทำได้แค่หาว่า team มี player คนไหนบ้าง แต่จะเราไม่สามารถใช้ในการหาย้อนกลับไปได้นั้นเองเลยต้องใช้ HasMany คู่กับ BelongsTo )
ต่อไปเราจะลองสร้าง relation แบบ [1:1] กันโดยใช้ HasOne คู่กับ BelongsTo นั่นเอง โดยก็ใช้งานคล้าย ๆ กันกับ [1:n] เลยแต่แค่มันจำกัดไว้แค่ 1 อย่างมีได้แค่ 1 อย่างเท่านั้น
db.people.hasOne (
db.idCard,
{
foreignKey: { name: 'pid', field: 'pid' },
}
);
db.idCard.belongsTo(db. people, { foreignKey: 'id' });
อย่างตัวอย่างด้านบนจะได้ความหมายว่า people 1 คนจะมี idCard ได้แค่ 1 ใบเท่านั้นโดย code ด้านบนจะทำการถ้า FK ในตารางของ idCard นะครับถ้าอยากได้ แบบกลับกันก็สลับรูปแบบกันแค่นั้นเองเอาง่าย ๆ อะไรที่ใช้ has จะเป็นตัวที่สร้าง FK ในตารางอื่นนั่นเอง
ต่อมาเราก็มาถึง relation สุดถ้าแล้วว [m:n] โดย relation นี่จะสร้างแปลก ๆ หน่อย โดยส่วนใช้เราจะสร้างมันโดยมี table มาเป็น table ตรงกลางที่คอยเก็บ PK ของทั้ง 2 table ที่มี relation กัน เราจะยกตัวเอย่างเป็น news กับ tag แล้วกันนะครับ
db.news.belongsToMany(db.tag, {
through: db.newsTag,
foreignKey: 'news_id',
otherKey: 'tag_id',
});
db.tag.belongsToMany(db.news, {
through: db.newsTag,
foreignKey: tag_id',
otherKey: 'news_id',
});
เท่านี้เราก็จะได้ relation [m:n] ของ tag กับ news แล้วโดยผ่าน newsTag นั่นเอง
ต่อไปเราก็มาดูการใช้งานหลังจากสร้าง relation แล้วกันดีกว่า
await team.findOne({
where: {
tid: 1
},
include: {
model: player
}
})
โดย code ด้านบนทำการ query ข้อมูลของทีม team และมีข้อมูลของ player ที่อยู่ในทีมติดมาด้วยแบบนี้ ( อย่าไปใส่ใจเรื่องทีมจริง ๆ ของนักกีฬานะครับ 😀 )
{
"tid": 1,
"name": "Real Madrid",
"league": "La Liga",
"players": [
{
"pid": 4,
"name": "Lionel Messi",
"age": 34,
"position": "ST",
"tid": 1
},
{
"pid": 14,
"name": "Marcelo",
"age": 33,
"position": "DF",
"tid": 1
}
]
}
แล้วถ้าใครอยากจะ filter player ก็ใส่ where ใน include ได้เลย
await team.findOne({
where: {
tid: 1
},
include: {
model: player,
where: { age: {[Op.gt]: 33} }
}
})
และนี่ก็คือผลที่ได้ไงล่ะ เราใช้ Operation ก็อย่าลืม defined มันก่อนใช้นะครับบบ
{
"tid": 1,
"name": "Real Madrid",
"league": "La Liga",
"players": [
{
"pid": 4,
"name": "Lionel Messi",
"age": 34,
"position": "ST",
"tid": 1
}
]
}
เอาล่ะแล้วก็จบไปแล้วสำหรับ เรื่องการใช้งาน Association ของ Sequelize หวังว่ามันจะช่วยเพื่อน ๆ ได้ไม่มากก็น้อยนะครับ สำหรับรอบหน้าจะเป็นเรื่องอะไรก็ขอให้รอติดตามกันนะครับบบ ( ถึงไม่รู้ว่าจะได้เขียนต่อหรือป่าวเถอะนะ5555 ) สำหรับใครที่อยากอ่าน Document ของ sequelize ก็กดไปอ่านได้ที่นี่เลย