پرتال شخصی مهدی رافعی

فروشگاه افق
ofogh-shop.com

نویسندگان
یکپارچگی در مدیریت توسعه وب
حفظ سلامت داده ها با استفاده از Rails و PostgreSQL

NoSQL عبارت جهانشمول جدیدی که برای دیتابیس های غیررابطه ای استفاده می شود، در میان توسعه دهندگان وب خیلی جا نیفتاده است. البته اطلاق NoSQL برای تعریف آنها کمی بی انصافی است و شامل فناوری های مختلفی می شود. با وجود این، تفاوت های پایه ای میان این دو نوع دیتابیس وجود دارد. همان طور که از نام NoSQL مشخص است، در این دیتابیس ها خبری از زبان SQL نیست و هر یک از آنها از زبان مشابه SQL خود استفاده می کند یا یک API شی ءگرا دارد.

یکی دیگر از این تفاوت ها، نبود جداول دوبعدی است. در حالی که دیتابیس های SQL منحصرا با این نوع جداول کار می کنند، دیتابیس های NoSQL به حالت جفت های نام ـ متغیر یا اشیای Hash داده را در خود ذخیره می کنند. در نهایت، دیتابیس های NoSQL قابلیت هایی که توسعه در دیتابیس های رابطه ای را ممکن می کند، ندارند.

بی شک انعطاف پذیری دیتابیس های NoSQL در سطوح مختلف جذاب است. درست همانند کارکرد با زبان های داینامیک که نیازی به تعریف متغیر پیش از استفاده از آنها وجود ندارد، می توان داده ها را در دیتابیس ذخیره کرد، بی آن که ساختاری برای دیتابیس تعریف کرده باشیم. مثلا اگر بخواهیم فیلد جدیدی برای فرد تعریف کنیم، کافی است دیتای جدید را به سرور بفرستیم، از این به بعد دیتابیس حواسش به فیلد جدید خواهد بود.

هر چند موارد دیگری وجود دارد که می خواهیم دیتابیس سختگیری داشته باشیم و یکپارچگی داده هایمان را حفظ کنیم. مثلا می خواهیم مطمئن باشیم حتی اگر مشکلی در کار با برنامه وجود داشت، یا داده ای وارد شد که مجاز نبود، دیتابیس آن داده بد را ذخیره نکند. بررسی این اطلاعات در سمت سرور و نه فقط در سمت نرم افزار گزینه خوبی است؛ چرا که در مقابل داده خراب، سپر محافظ دیگری استفاده می شود.

Ruby On Rails، فریم ورک قدرتمند طراحی وب که به صورت پیش فرض از دیتابیس های زیادی پشتیبانی می کند، در وهله اول، به سمت MySQL متمایل است، اما کار با دیتابیس های بزرگ تری چون PostgreSQL برای این فریم ورک دشوار است؛ زیرا از کلیدهای خارجی پشتیبانی نمی کند.

برای بررسی امن بودن داده ها، بهتر است مکانیسم بررسی اطلاعاتی را در دیتابیس قرار دهیم و از سطح نرم افزار آن را بررسی کنیم. اضافه کردن پشتیبانی از کلیدهای خارجی و مکانیسم CHECK در PostgreSQL در ادامه مطلب آورده شده است.

● داده را در کجا چک کنیم؟

پیش از آن که وارد کد و پیاده سازی شویم، بهتر است نخست به این بپردازیم که کجا و چگونه داده را بررسی کنیم. همان طور که پیشتر اشاره شد، می توان داده را در دو سطح نرم افزار و دیتابیس بررسی کرد؛ هر چند برنامه نویسان تنبل تر ترجیح می دهند فقط در سطح نرم افزار و با قابلیت های پیش فرض Rails داده ها را بررسی کنند.

بررسی داده در سطح نرم افزار، مزایای خودش را دارد. پیاده سازی آسان تر خواهد شد و معمولا هم بدرستی کار می کند. به خصوص در محیط Rails می توان با یک زبان (Ruby)، اطلاعات لازم را در مدل قرار داد و بعد از آن استفاده کرد.

اما همان طور که پیشتر گفتیم، اگر اطلاعات را فقط در سطح نرم افزار بررسی کنیم، ممکن است این اتفاق رخ بدهد که اطلاعات مستقیما در دیتابیس تزریق شود و کار به هم بریزد. حتی اگر احتمال به هم ریخته شدن اطلاعات را بسیار اندک در نظر بگیریم، بازگشت و تعمیر این دیتابیس کار دشواری خواهد بود.

هر چند بسیاری از نرم افزارهای تحت وب این طور طراحی شده است و حفره امنیتی بزرگی وجود ندارد، اما این چیزی است که باید از آن اجتناب کرد.

البته روش دیگر، اشتباه بزرگ تری را رقم می زند؛ زیرا چک کردن فقط در محیط دیتابیس باعث مشکلات عظیم تری خواهد شد. مثلا فرض کنیم جدولی با محتوای NOT NULL در دیتابیس داریم، یعنی این فیلد نمی تواند مقدار NULL به خود بگیرد. اگر در مرحله نرم افزار جلوی خطا را نگیریم، اطلاعات خراب وارد دیتابیس می شود. هر چند دیتابیس خراب نشده، اما نرم افزار ممکن است پیام خطا بدهد و رفع این ایراد هم دشوار و گیج کننده خواهد بود.

بنابراین، هرقدر هم که کار دشوار و سختی باشد، بهترین روش برای جلوگیری از این اتفاقات، دوباره کاری در مرحله چک کردن اطلاعات است. ایجاد شرط هم داخل نرم افزار و هم داخل دیتابیس می تواند مشکلات را بخوبی حل کند. در Rails، client_side_validations می تواند قوانین مدل را گرفته و آنها را به صورت جاوااسکریپت درون فرم ها تعبیه کند.

● کلیدهای خارجی

با این پیش زمینه می توان فرض کرد که می خواهیم یک تقویم قرار ملاقات ساده بسازیم. می خواهیم افراد مختلف را بشناسیم.

هر یک از این افراد مشخصاتی دارند (نام، نام خانوادگی، آدرس ایمیل و شماره تلفن) و قرارهایشان را نیز باید ثبت کنیم (که زمان و تاریخ آنها ثبت خواهد شد، همچنین فرد مقابل که قرار است با او جلسه گذاشته شود نیز نامش باید درج شود،

یک فیلد توضیحات که می توان موضوع جلسه را در آن مشخص کرد.)

در سطح دیتابیس، با جدول ساده ای روبه رو هستیم:

CREATE TABLE People

,id SERIAL)

, first_name TEXT NOT NULL

, last_name TEXT NOT NULL

, email TEXT NOT NULL

, phone TEXT NOT NULL

PRIMARY KEY(id)؛)

CREATE TABLE Appointments

, id SERIAL ,)

person_id INTEGER REFERENCES People NOT NULL

, notes TEXT NOT NULL

PRIMARY KEY(id)؛)

به عبارت REFERENCES People دقت کنید. این عبارت دو جدول را به یکدیگر متصل می کند. مثلا اگر بخواهیم اطلاعاتی را از جدول People حذف کنیم، با این خطا مواجه می شویم:

atf=# DELETE FROM People WHERE id = ۱;

ERROR: update or delete on table "people" violates foreign key

constraint "appointments_person_id_fkey" on table "appointments"

DETAIL: Key (id)=(۱) is still referenced from table "appointments".

از آنجا که Appointments.person_id کلید خارجی People.id است، سیستم پیغام خطا می دهد. این جور ارتباطات برای نرم افزار بسیار مفید خواهد بود. این یعنی اگر کسی در سیستم قرارها وارد شود، نمی توان آن را حذف کرد.

● پیاده سازی در Rails

اگر این جداول بخشی از یک نرم افزار تحت وب باشد که در Ruby On Rails مشغول توسعه آنها هستیم، در این صورت می توان از database migration برای تولید آنها استفاده کرد.

class CreatePeopleAndAppointments « ActiveRecord::Migration

def change

create_table :people do |t|

t.string :first_name, :null =» false

t.string :last_name, :null =» false

t.string :email, :null =» false

t.string :phone, :null =» false

t.timestamps

end

create_table :appointments do |t|

t.integer :person_id, :null =» false

t.text :notes, :null =» false

t.timestamps

end

end

end

این فایل، ایجاد جداول را به عهده می گیرد، اما کلیدهای خارجی در آن وجود ندارد، به این منظور اگر رکوردی از People را حذف کنیم، ممکن است دیتابیس خراب شود. برای استفاده از کلیدهای خارجی، باید SQL صحیح را مستقیما به دیتابیس بفرستیم.

خوشبختانه روش ساده تری برای این کار وجود دارد. Foreigner gem که توسط برنامه نویس، Matthew Higgins نوشته شده است، می تواند با MySQL و PostgreSQL همخوان شود، و Syntax جدیدی ایجاد کرده است که می توان کلیدهای خارجی را در migrationها ایجاد یا حذف کرد. بعد از نصب این gem کافی است از دستوری مشابه دستور زیر استفاده کنیم:

class AddForeignKey « ActiveRecord::Migration

def up

add_foreign_key:appointments,:people

end

def down

remove_foreign_key:appointments,:people

end

end

نکته مهم این است که باید این پیاده سازی را در مدل Rails نیز انجام دهیم، در غیر این صورت امکان دارد اتفاقی رخ دهد و آن هم این است که مدل داده را قبول می کند، اما دیتابیس آن را انجام نمی دهد و errorعجیبی به کاربر نشان داده می شود.

حالا بیایید فرض کنیم هم اکنون پروژه ای زیر دست دارید، اما کلیدهای خارجی را در آن تعریف نکرده اید. برای تصحیح می توان یکی یکی جداول را بررسی، سپس کلیدهای خارجی آنها را تعریف کرد. اما Immigrant gem برای Rails خودش از مدل های Rails برای تشخیص کلیدهای خارجی استفاده می کند و نیازی به دوباره کاری در مرحله سرورها وجود نخواهد داشت. کافی است مدل های rails را تصحیح کرده، سپس از این gem استفاده کنید.

محمدرضا قربانی

روزنامه جام جم ( www.jamejamonline.ir )

---------------------------------------------------------

فروشگاه افق ؛ با کالاها و خدماتی متمایز

www.ofogh-shop.com

نظرات  (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی