1. บทนำ
เมื่อสร้างแอปพลิเคชันที่ขับเคลื่อนด้วยข้อมูล มักจะจำเป็นต้องบันทึกข้อความและข้อมูลไบนารี โปรแกรมดังกล่าวอาจจำเป็นต้องจัดเก็บรูปภาพ, PDF, ไฟล์ Word หรือข้อมูลไบนารีอื่นๆ มีสองวิธีในการจัดเก็บข้อมูลไบนารีนี้: ในระบบไฟล์ของเว็บเซิร์ฟเวอร์และการเพิ่มการอ้างอิงไปยังไฟล์ที่เกี่ยวข้องในฐานข้อมูล หรือในฐานข้อมูลโดยตรง
ข้อมูลที่เป็นข้อความ เช่น สตริง ตัวเลข วันที่ GUID ค่าทางการเงิน ฯลฯ มีคำจำกัดความประเภทข้อมูลที่เหมาะสมและสอดคล้องกันในระบบฐานข้อมูล ตัวอย่างเช่น ใน Microsoft SQL Server คุณสามารถใช้ชนิดข้อมูล int เพื่อจัดเก็บค่าจำนวนเต็ม และในการจัดเก็บค่าสตริง คุณสามารถใช้ชนิด varchar หรือ nvarchar นอกจากนี้ ฐานข้อมูลยังมีคำจำกัดความประเภทสำหรับการจัดเก็บข้อมูลไบนารีอีกด้วย ใน Microsoft SQL SERVER 2000 และเวอร์ชันก่อนหน้า ชนิดข้อมูลรูปภาพถูกใช้เพื่อเก็บข้อมูลไบนารี ใน SQL SERVER 2005 จะใช้ชนิดข้อมูล varbinary (MAX) ประเภทข้อมูลเหล่านี้สามารถจัดเก็บข้อมูลไบนารีที่มีขนาดสูงสุด 2GB โดยใช้วิธีใดวิธีหนึ่งจากสองวิธีข้างต้น
อย่างไรก็ตาม เมื่อจัดเก็บข้อมูลไบนารี่โดยตรงในฐานข้อมูล จำเป็นต้องมีการทำงานเพิ่มเติมบางอย่างเพื่อแทรก อัปเดต และเรียกข้อมูลไบนารี่ โชคดีที่เราสามารถสรุปการดำเนินการ T-SQL ระดับต่ำที่ซับซ้อนนี้ผ่านไลบรารีการเข้าถึงข้อมูลระดับที่สูงกว่า เช่น ADO.NET เพื่อให้ปัญหาค่อนข้างง่าย อย่างไรก็ตาม การทำงานกับข้อมูลไบนารีผ่าน ADO.NET จะแตกต่างจากการทำงานกับข้อมูลข้อความเล็กน้อย ในบทความนี้ เราจะวิเคราะห์วิธีการใช้ ADO.NET และตัวควบคุม ASP.NET 2.0 SqlDataSource เพื่อจัดเก็บและดึงข้อมูลไฟล์รูปภาพโดยตรงจากฐานข้อมูล โปรดอ่านต่อ!
2. การเปรียบเทียบระหว่างการจัดเก็บข้อมูลในฐานข้อมูลและการเก็บไว้ในระบบไฟล์
ตามที่แนะนำไป เมื่อจับข้อมูลไบนารี่ในแอปพลิเคชัน ข้อมูลไบนารี่สามารถจัดเก็บได้โดยตรงในฐานข้อมูลหรือเป็นไฟล์บนเว็บ ระบบไฟล์ - มีเพียงการอ้างอิงถึงไฟล์ในฐานข้อมูลเท่านั้นที่ยังคงอยู่ จากประสบการณ์ของฉัน ฉันพบว่านักพัฒนาส่วนใหญ่ชอบจัดเก็บข้อมูลไบนารี่ในระบบไฟล์ ด้วยเหตุผลหลักๆ ดังต่อไปนี้:
· ใช้ความพยายามน้อยลง - การจัดเก็บและการเรียกข้อมูลไบนารี่ที่เก็บไว้ในฐานข้อมูลต้องใช้ความพยายามในการเขียนโค้ดมากขึ้น ยิ่งไปกว่านั้น การอัปเดตข้อมูลไบนารี่เหล่านี้จะง่ายขึ้น - ไม่จำเป็นต้องสื่อสารกับฐานข้อมูล เพียงแค่แก้ไขไฟล์โดยตรง!
· URL ที่ชี้ไปยังไฟล์จะตรงกว่า - ดังที่เราจะเห็นในบทความนี้ เพื่อให้สามารถเข้าถึงข้อมูลไบนารีที่จัดเก็บไว้ในฐานข้อมูล เราจำเป็นต้องสร้างเพจ ASP.NET อื่นที่สามารถส่งคืนข้อมูลนั้นได้ โดยทั่วไปแล้ว ตัวระบุเฉพาะที่สอดคล้องกับบันทึกที่เกี่ยวข้องในฐานข้อมูล (ส่งคืนข้อมูลไบนารี) จะถูกส่งไปที่หน้านี้ ผลลัพธ์ก็คือเพื่อเข้าถึงข้อมูลไบนารี - เช่นรูปภาพที่อัปโหลด - URL จะมีลักษณะดังนี้ http://www.yourserver.com/ShowImage.aspx?ID=4352 ในขณะที่รูปภาพนั้นถูกจัดเก็บโดยตรงในไฟล์ใน ระบบ URL จะตรงกว่า - เช่น http://www.yourserver.com/UploadedImages/Sam.jpg
· รองรับเครื่องมือที่ดีกว่าสำหรับการแสดงรูปภาพ - หากคุณใช้ ASP.NET 2.0 คุณสามารถใช้ตัวควบคุม ImageField ในตัวควบคุม GridView หรือ DetailView เพื่อแสดงรูปภาพ (เส้นทางรูปภาพถูกเก็บไว้ในฐานข้อมูล) อย่างไรก็ตาม น่าเสียดายที่ ImageField นี้ไม่สามารถแสดงข้อมูลรูปภาพในฐานข้อมูลได้โดยตรง (เนื่องจากจำเป็นต้องสอบถามเพจภายนอกและส่งกลับข้อมูลที่เกี่ยวข้อง)
· ประสิทธิภาพ - เนื่องจากไฟล์ไบนารีถูกจัดเก็บไว้ในระบบไฟล์ของเว็บเซิร์ฟเวอร์มากกว่าในฐานข้อมูล แอปพลิเคชันจึงสามารถเข้าถึงข้อมูลในฐานข้อมูลได้น้อยลง ซึ่งช่วยลดข้อกำหนดในฐานข้อมูล และลดข้อกำหนดบนเว็บและความแออัดของเครือข่ายระหว่างกัน เซิร์ฟเวอร์ฐานข้อมูล
ข้อได้เปรียบหลักของการจัดเก็บข้อมูลลงในฐานข้อมูลโดยตรงคือทำให้ข้อมูล "มีอยู่ในตัวเอง" ขณะนี้ข้อมูลทั้งหมดอยู่ในฐานข้อมูลแล้ว การสนับสนุนข้อมูล การเคลื่อนย้ายข้อมูลระหว่างเซิร์ฟเวอร์ฐานข้อมูล การจำลองฐานข้อมูล ฯลฯ จะง่ายขึ้นมาก เนื่องจากไม่จำเป็นต้องกังวลเกี่ยวกับการคัดลอกหรือสำรองเนื้อหาไบนารีที่จัดเก็บไว้ในระบบไฟล์
เช่นเคย โซลูชันการจัดเก็บข้อมูลที่เลือกจะขึ้นอยู่กับสถานที่ใช้งานจริงและความต้องการทางธุรกิจ ตัวอย่างเช่น ฉันพัฒนาไคลเอนต์ที่ต้องจัดเก็บข้อมูลไบนารี่ไว้ในฐานข้อมูล เนื่องจากซอฟต์แวร์การรายงานที่พวกเขาใช้สามารถรวมข้อมูลไบนารีในรายงานได้เท่านั้น หากมาจากฐานข้อมูล ในอีกกรณีหนึ่ง เพื่อนร่วมงานของฉันกำลังทำงานในโครงการที่เว็บแอปพลิเคชันจำเป็นต้องใช้ไบนารีและพร้อมใช้งานผ่าน FTP ซึ่งในกรณีนี้จำเป็นต้องจัดเก็บข้อมูลไบนารีไว้ในระบบไฟล์
3. สร้างตารางฐานข้อมูลเพื่อเก็บข้อมูลไบนารี
ส่วนที่เหลือของบทความนี้จะวิเคราะห์แอปพลิเคชันแกลเลอรีรูปภาพ ASP.NET 2.0 ที่ฉันเขียนโดยใช้ Microsoft SQL Server 2005 Express Edition เพื่อสาธิตแนวคิดโดยตรงที่เกี่ยวข้องกับการจัดเก็บและการเรียกข้อมูลไบนารีใน ฐานข้อมูล
แบบจำลองข้อมูลของแอปพลิเคชันแกลเลอรีรูปภาพนี้ประกอบด้วยตาราง - รูปภาพ โดยที่แต่ละเรกคอร์ดสอดคล้องกับรูปภาพในแกลเลอรี ช่อง MIMEType ของตารางรูปภาพนี้จะจัดเก็บประเภท MIME ของรูปภาพที่อัพโหลด (รูปภาพ/jpeg สำหรับไฟล์ JPG, รูปภาพ/gif สำหรับไฟล์ GIF ฯลฯ) ประเภท MIME ที่นี่จะระบุวิธีสร้างข้อมูลไบนารีให้กับเบราว์เซอร์ คอลัมน์ ImageData จะจัดเก็บเนื้อหาไบนารีที่แท้จริงของรูปภาพ
4. อัปโหลดรูปภาพและจัดเก็บข้อมูลไบนารี่โดยใช้โค้ด ADO.NET แกลเลอ
รีรูปภาพนี้อนุญาตให้ผู้เยี่ยมชมอัปโหลดไฟล์รูปภาพ (รูปแบบ GIF, JPG และ PNG) ลงในแอปพลิเคชันนี้ เมื่ออัปโหลดแล้ว บันทึกใหม่จะถูกเพิ่มลงในตารางรูปภาพ และเนื้อหาของไฟล์รูปภาพจะถูกจัดเก็บไว้ในคอลัมน์ ImageData ของบันทึกใหม่ ในการอัปโหลดไฟล์จากเว็บเบราว์เซอร์ไปยังเว็บเซิร์ฟเวอร์ใน ASP.NET 2.0 ตัวควบคุม FileUpload จะถูกนำมาใช้ในตัวอย่างนี้ การใช้ตัวควบคุม FileUpload นั้นง่ายมาก เพียงลากจากแถบเครื่องมือไปยังเพจของคุณ ท้ายที่สุด การควบคุม FileUpload นี้จะถูกสร้างขึ้นในเบราว์เซอร์ของผู้ใช้ในรูปแบบการอัพโหลดไฟล์มาตรฐาน - ปุ่ม "เรียกดู" (เมื่อคลิก) อนุญาตให้ผู้ใช้เลือกไฟล์จากฮาร์ดไดรฟ์เพื่ออัพโหลดไปยังเว็บเซิร์ฟเวอร์
ตัวอย่างเช่น ในการสร้างอินเทอร์เฟซสำหรับการเพิ่มรูปภาพใหม่ ฉันใช้ตัวควบคุมกล่องข้อความเพื่อบันทึกชื่อเรื่องของรูปภาพ และตัวควบคุม FileUpload เพื่อให้ผู้ใช้สามารถระบุรูปภาพที่จะอัปโหลด:
<b>Title:</b>
<asp:TextBox ID="PictureTitle" runat="server" />
<br />
<b>ภาพ:</b>
<asp:FileUpload ID="UploadedFile" runat="server" />
<br />
<asp:LinkButton ID="btnInsert" runat="server" Text="Insert" />
<asp:LinkButton ID="btnCancel" runat="server" Text="Cancel" />
โค้ดด้านบนจะสร้างหน้าที่ผู้ใช้สามารถระบุไฟล์จากฮาร์ดไดรฟ์ของตนเพื่ออัปโหลดไปยังเว็บเซิร์ฟเวอร์
เมื่อผู้ใช้เลือกไฟล์และส่งแบบฟอร์ม (เช่น คลิกปุ่ม "แทรก") เนื้อหาไบนารีของไฟล์ที่ระบุจะถูกส่งไปยังเว็บเซิร์ฟเวอร์ จากโค้ดฝั่งเซิร์ฟเวอร์ ข้อมูลไบนารีนี้จะพร้อมใช้งานผ่านคุณสมบัติ PostFile.InputStream ของตัวควบคุม FileUpload ดังที่แสดงโดยมาร์กอัปและโค้ดต่อไปนี้:
Protected Sub btnInsert_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnInsert คลิก
'ตรวจสอบให้แน่ใจว่าอัพโหลดไฟล์สำเร็จ
หาก UploadedFile.PostedFile ไม่มีอะไรเลยหรือสตริงอื่น IsNullOrEmpty (UploadedFile.PostedFile.FileName) หรือ Else UploadedFile.PostedFile.InputStream ไม่มีอะไรแล้ว
...แสดงข้อความแสดงข้อผิดพลาด...
ออกจากย่อย
สิ้นสุดถ้า
'ตรวจสอบให้แน่ใจว่าเรากำลังทำงานกับไฟล์ JPG หรือ GIF
ส่วนขยาย Dim As String = Path.GetExtension(UploadedFile.PostedFile.FileName).ToLower()
Dim MIMEType As String = ไม่มีเลย
เลือกส่วนขยายกรณีและปัญหา
กรณี ".gif"
ชนิดไมม์ = "รูปภาพ/gif"
ตัวพิมพ์ ".jpg", ".jpeg", ".jpe"
MIMEType = "รูปภาพ/jpeg"
กรณี ".png"
ชนิดไมม์ = "รูปภาพ/png"
กรณีอื่น
'การอัปโหลดประเภทไฟล์ไม่ถูกต้อง... มีข้อความแสดงข้อผิดพลาดปรากฏขึ้น...
ออกจากย่อย
สิ้นสุด เลือก
'เชื่อมต่อกับฐานข้อมูลและแทรกบันทึกใหม่ลงในตารางผลิตภัณฑ์
การใช้ myConnection เป็น SqlConnection ใหม่ (ConfigurationManager.ConnectionStrings ("ImageGalleryConnectionString").ConnectionString)
Const SQL As String = "INSERT INTO [Pictures] ([Title], [MIMEType], [ImageData]) VALUES (@Title, @MIMEType, @ ข้อมูลรูปภาพ)"
หรี่ myCommand เป็น SqlCommand ใหม่ (SQL, myConnection)
myCommand.Parameters.AddWithValue("@Title", PictureTitle.Text.Trim())
myCommand.Parameters.AddWithValue("@MIMEType", MIMEType)
'โหลด InputStream ของตัวควบคุม FileUpload ลงในอาร์เรย์ไบต์
Dim imageBytes (UploadedFile.PostedFile.InputStream.Length) เป็นไบต์
UploadedFile.PostedFile.InputStream.Read (imageBytes, 0, imageBytes.Length)
myCommand.Parameters.AddWithValue("@ImageData", imageBytes)
myConnection.Open()
myCommand.ExecuteNonQuery()
myConnection.ปิด()
สิ้นสุดการใช้
สิ้นสุด
SubHere ตัวจัดการเหตุการณ์นี้จะตรวจสอบให้แน่ใจก่อนว่าไฟล์ได้รับการอัปโหลดแล้ว จากนั้นจะกำหนดประเภท MIME ตามนามสกุลไฟล์ที่กำลังอัปโหลด
ส่วนที่น่าสังเกตมากที่สุดของข้างต้นคือส่วนของโค้ดที่ตั้งค่าพารามิเตอร์ @ImageData ขั้นแรก สร้างอาร์เรย์ไบต์ชื่อ imageBytes และทำให้ความยาวของอาร์เรย์ตรงกับ InputStream ของไฟล์ที่กำลังอัปโหลด จากนั้น ใช้เมธอด Read จาก InputStream เพื่อเติมเนื้อหาไบนารีลงในอาร์เรย์ไบต์นี้ โปรดทราบว่าอาร์เรย์ไบต์นี้ระบุเป็นค่าของ @ImageData