1. مقدمة
عند إنشاء تطبيقات تعتمد على البيانات، غالبًا ما يكون من الضروري التقاط البيانات النصية والثنائية. قد يحتاج مثل هذا البرنامج إلى تخزين الصور أو ملفات PDF أو ملفات Word أو البيانات الثنائية الأخرى. هناك طريقتان لتخزين هذه البيانات الثنائية: على نظام ملفات خادم الويب وإضافة مرجع إلى الملف المقابل في قاعدة البيانات أو مباشرة في قاعدة البيانات نفسها.
البيانات النصية مثل السلاسل والأرقام والتواريخ والمعرفات الفريدة العمومية (GUIDs) والقيم النقدية وما إلى ذلك - لها تعريفات مناسبة ومطابقة لنوع البيانات في نظام قاعدة البيانات. على سبيل المثال، في Microsoft SQL Server، يمكنك استخدام نوع البيانات int لتخزين قيمة عددية؛ ولتخزين قيمة سلسلة، يمكنك استخدام نوع varchar أو nvarchar. بالإضافة إلى ذلك، توفر قاعدة البيانات أيضًا تعريفات النوع لتخزين البيانات الثنائية. في Microsoft SQL SERVER 2000 والإصدارات السابقة، يتم استخدام نوع بيانات الصورة لتخزين البيانات الثنائية؛ وفي SQL SERVER 2005، يتم استخدام نوع البيانات المتغير (MAX). أنواع البيانات هذه قادرة على تخزين بيانات ثنائية يصل حجمها إلى 2 جيجابايت باستخدام أي من الطريقتين أعلاه.
ومع ذلك، عند تخزين البيانات الثنائية مباشرة في قاعدة البيانات، يلزم القيام ببعض العمل الإضافي لإدراج البيانات الثنائية وتحديثها واسترجاعها. لحسن الحظ، يمكننا تجريد عملية 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 أو عنصر تحكم عرض التفاصيل لعرض صورة (يتم تخزين مسار الصورة في قاعدة البيانات). ومع ذلك، لسوء الحظ، لا يمكن لـ 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 هذا في متصفح المستخدم كنموذج قياسي لتحميل الملفات - يتيح زر "تصفح" (عند النقر عليه) للمستخدم تحديد ملف من محرك الأقراص الثابتة الخاص به لتحميله إلى خادم الويب.
على سبيل المثال، لإنشاء واجهة لإضافة صورة جديدة، استخدمت عنصر تحكم TextBox لالتقاط عنوان الصورة، وعنصر تحكم FileUpload للسماح للمستخدم بتحديد الصورة المراد تحميلها:
<b>Title:</b>
<asp:معرف مربع النص = "PictureTitle" runat = "الخادم" />
<br />
<ب>الصورة:</ب>
<asp: معرف FileUpload = "UploadedFile" runat = "الخادم" />
<br />
<asp: معرف LinkButton = "btnInsert" runat = "الخادم" نص = "إدراج" />
<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 لا شيء، أو Else String.IsNullOrEmpty(UploadedFile.PostedFile.FileName) أو Else UploadedFile.PostedFile.InputStream لا شيء إذن
...عرض رسالة الخطأ...
الخروج من الباطن
نهاية إذا
"تأكد من أننا نعمل مع ملف JPG أو GIF
تمديد خافت كسلسلة = Path.GetExtension(UploadedFile.PostedFile.FileName).ToLower()
Dim MIMEType كسلسلة = لا شيء
حدد امتداد الحالة
الحالة ".gif"
نوع MIMEType = "صورة/gif"
حالة ".jpg"، ".jpeg"، ".jpe"
نوع MIMEType = "صورة/jpeg"
الحالة ".png"
نوع MIMEType = "صورة/png"
حالة أخرى
"تحميل نوع ملف غير صالح... تظهر رسالة خطأ...
الخروج من الباطن
إنهاء حدد
"الاتصال بقاعدة البيانات وإدراج سجل جديد في جدول المنتجات".
استخدام myConnection As New 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 إلى صفيف بايت
تعتيم imageBytes (UploadedFile.PostedFile.InputStream.Length) كبايت
UploadedFile.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length)
myCommand.Parameters.AddWithValue("@ImageData"، imageBytes)
myConnection.Open()
myCommand.ExecuteNonQuery()
myConnection.Close()
إنهاء الاستخدام
End
Subهنا، يتأكد معالج الحدث هذا أولاً من تحميل الملف. ثم يحدد نوع MIME بناءً على امتداد الملف الذي يتم تحميله.
الجزء الأكثر جدارة بالملاحظة مما سبق هو قسم التعليمات البرمجية الذي يقوم بتعيين معلماتImageData. أولاً، قم بإنشاء مصفوفة بايت باسم imageBytes واجعل طولها هو طول InputStream المقابل للملف الذي يتم تحميله. ثم استخدم أسلوب القراءة من InputStream لملء المحتوى الثنائي في صفيف البايت هذا. لاحظ أنه تم تحديد صفيف البايت هذا كقيمةImageData.