# پایگاه‌های داده > سایر پایگاه‌های داده > MySQL >  Update اطلاعات ثبت شده بر روی سرور

## tabib_m

با سلام

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

از یه لحاظ مشکلی نیست چون میشه یک فایل sql از دیتابیس تحویل گرفت و فرستاد روی هاست و اجراش کرد تا دیتابیس هاست پر شه.

اما مشکل من اینه که من دائما میخوام روی لوکال اطلاعات پر (و یا ویرایش و حذف) کنم و بعد دیتابیس رو روی هاست بفرستم.

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

یه راه حل میخواستم که بتونم فقط تغییراتی که روی لوکال انجام میشه رو روی سرور اجرا کنم. یعنی فقط اگه 10 رکورد به دیتابیس اظافه شده میخوام همون ده رکورد اینسرت شه نه همه ی دیتابیس

امیدوارم که منظورم رو رسونده باشم.

----------


## javad_hosseiny

برای این منظور باید به هنگام افزایش، اصلاح و یا هرگونه در اطلاعات تغییرات را در یک فایل log ذخیره کرده (البته منظورم بصورت یک دستور query)  می باشد و سپس فقط فایل لوگ خود را آپلود کنید و آن را بصورت یک فایل sql فراخوانی کنید
(من هم در یک برنامه کتابفروشی الکترونیکی همین مشکل را داشتم (حجم اطلاعات بسیار بالا) و اپراتور بصورت آفلاین (بر روی لوکال) کار می کرد و در خود برنامه امکان آپلود فایل لوگر را فراهم کردم و پس از اتصال به اینترنت کافی بود که گزینه آپلود را انتخاب کند (تا هم فایل آپلود شود و هم بر روی سرور اجرا شود) 
(نکته فقط در این است که در نقطه ذخیره سازی (منظور هرگونه تغییری در جداول هست) یک فایلی دیگر را فراخوانی کنید که وظیفه اش ذخیره تغییرات بصورت دستور query  در یک فایل جداگانه می باشد)

----------


## tabib_m

از کمکی که کردید خیلی ممنونم

ولی به نظر من این کار یخورده خطرناکه ، چون آی دی هایی که روی لوکال ثبت میشن ممکنه (فقط ممکنه) به خاطر یک اشتباه یا اظافه نکردن یک query توی فایل با آی دی هایی که روی هاست ثبت میشن فرق کنه.
به همین خاطر برای ویرایش یک رکورد یا حذف اون اگر از آی دی بخوایم استفاده کنیم اونوقت رکوردی که روی لوکال حذف میشه با رکوردی که روی هاست حذف میشه فرق میکنه. البته احتمال وقوع چنین اتفاقی خیلی بعیده ، ولی به هر حال در صورتی که اتفاق بیفته خیلی حال آدم رو میگیره!
میخواستم بدونم شما تو برنامتون با این مشکل بر نخوردید (با مشکل جابجایی آی دی ها)؟




> من هم در یک برنامه کتابفروشی الکترونیکی ...


(میشه اگه روی اینترنت فعالیت داره بگید کدوم کتابفروشی؟)

----------


## Achchan

Hi,
*First solution*: Add a timestamp or date column to your table.So you can select only the rows after the max(date_column) on server,and transfer them.But you will need tigger for updating this column on local server and this is not available till mysql 5.0.x.
*Second solution*:Use specific ID range every period,for example first day,you should assign Id's from 1 to 100,second day from 101 to 200 and so on.
This may help you if you don't have many rows.Other alternative but similar solution is to use IDs which mod 2 is 0 at first day,ID mod 3 = 0 at second day,ID mod 5 = 0 at third day and go on with prime numbers!This will prevent from ID contention.
*Third solution*: Consider data Replication if there is such a built-in solution in mysql(I am not aware personally).Your usecase is a typical replication problem in Oracle and SQL Server.

----------


## Identifier

شما میتونی یک برنامه با پرل بنویسین و انو توی background فرار بدید که به این صورت کار کنه
هر از 1 دقیقه دیتابیس رو Export کنه با 1 دقیق قبل مفایسه کنه اگر تفاوت داشت آپلود کنه
یا از الگوریتم های متفاوتی شبیه این من شخصا خودم از این روش استفاده میکنم و برنامه رو به صورت یک سرویس در آوردم میاد حجم رو چک میکنه اگر تغییر داشت ارسال میکنه

----------


## tabib_m

> شما میتونی یک برنامه با پرل بنویسین و انو توی background فرار بدید که به این صورت کار کنه
> هر از 1 دقیقه دیتابیس رو Export کنه با 1 دقیق قبل مفایسه کنه اگر تفاوت داشت آپلود کنه
> یا از الگوریتم های متفاوتی شبیه این من شخصا خودم از این روش استفاده میکنم و برنامه رو به صورت یک سرویس در آوردم میاد حجم رو چک میکنه اگر تغییر داشت ارسال میکنه


من منظورم این نبود که میخوام اطلاعاتم به صورت اتوماتیک آپدیت شه. (یعنی اون طور که من فهمیدم شما منظور من رو اینطوری گرفتید) من میخوام فقط تغییراتی که روی لوکال انجام میشه روی هاست هم انجام بشه. و نمیخوام هر دفعه برای آپدیت اطلاعات کل دیتابیس رو بفرستم روی هاست.

----------


## oxygenws

مشکل ایشون اینه که ممکنه اطلاعاتی **حذف** شده باشه یا تغییر کرده باشه.

به نظر من اگر بانک رو مشترک تعریف کنی بهتره، یعنی روی لوکال هم با بانک روی اینترنت ات کار کنی.

----------


## Identifier

اینجوری اونوقت همیشه لوکال به اینترنت متصل باشه بازم فکر نمی کنم مشکل دوستمون حل بشه

----------


## mzjahromi

می تونی مثل ویندوز از یک Flag  استفاده کنی؟ هر فایلی که تغییر کرده بود اون flag  ریست بشه وقتی هم میخوای رو سرور منتقلشون کنی بعد از انتقال یک چک دوباره انجام بده

----------


## javad_hosseiny

این نکته (بروزرسانی اطلاعات براساس تغییرات جداول) را همانطور که قبلا گفتم اگر درست عمل کنید مشکل بهم ریختن اطلاعات نیست ( یا متفاوت بدون آی دی ها را ندارد) 
چرا که در حقیقت شما همانکاری را که می بایستی mysql انجام دهد جدا لوگ برداری می کنید
ودر حقیقت همان دستورات را دوباره تکرار می کنید (ولی این بار بر روی سرور)

در حالتی که همیشه به اینترنت متصل باشی (یعنی در لوکال کار کنید و با دیتابیس سرور مشغول باشید (در تعریف کانکش ، کانکش سرور را تعریف کنید)) چرا مشکل حل می شود (چرا که در حقیقت یک مبنا وجود دارد) ولی خوب بالطبع به هنگام تغییرات در جداول به علت بروزررسانی اطلاعات در سرور اینترنتی زمان بیشتری می برد و خوب باید همواره به اینترنت متصل باشید
در این حالت که بنده عرض کردم (البته به شرطی که همواره اطلاعات شما برتر است اطلاعات سرور اینترنتی باشد) (یعنی نباشد موردی که در روی سرور اینترنتی اصلاح یا تغییر یا ... داده اید و بر روی لوکال شما ثبت نشده باشد) (یعنی همواره از لوکال به اینترنت منتقل شود) (البته شما می تونید اطلاعات سرور را بصورت یک فایل sql ذخیره بکنید و سپس بر روی لوکال فراخوانی کنید (انتقال اطلاعات از سرور به لوکال)) ولی همواره تغییرات یا ... بر روی لوکال شما باشد، مشکلی پیش نمی آید. 
مورد کتابفروشی الکترونیکی را که هم عرض کردم در یک شبکه اینترانت مشغول هست و هنوز کاربران در حالت پر کردن اطلاعات هستند (چیزی حدود 60000 رکورد (مشخصات کامل کتاب)) و هنوز بر روی شبکه اینترنت در دسترس نیست

----------


## cybercoder

oxygenws درست میگه باید با دیتابیست از روی لوکال کار کنی

با دلفی به راحتی این کار رو میشه کرد

----------


## tabib_m

من برای این روی لوکال میخوام کار کنم که به اینترنت وصل نباشم. و تغییراتی رو که میخوام بدم اول مطمئن شم که درست کار کردم بعد روی هاست انجامشون بدم. اگر نه که اصلا ورودی اطلاعاتم رو روی خود هاست انجام میدادم.

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

----------


## oxygenws

می تونی از binary log های MySQL استفاده کنی.
http://dev.mysql.com/doc/refman/4.1/en/binary-log.html

البته می تونی از Query log ها هم استفاده کنی، ولی فکر کنم همون binary log ها راحت تر باشه.
http://dev.mysql.com/doc/refman/4.1/en/query-log.html

ولی نهایتا باید خودت براش کد بزنی :)
نمونه یک باینری لاگ:

mysql> show binlog events;                                                                                                
   show binlog events;                                                                                                       
   +------------------------+-----+------------+-----------+--------------+--------------------------------------------+     
   | Log_name               | Pos | Event_type | Server_id | Orig_log_pos | Info                                       |     
   +------------------------+-----+------------+-----------+--------------+--------------------------------------------+     
   | third-fl-71-bin.000001 |   4 | Start      |         1 |            4 | Server ver: 4.1.1-alpha-log, Binlog ver: 3 |     
   | third-fl-71-bin.000001 |  79 | Query      |         1 |           79 | use `test`; create table j2 (a int)        |     
   | third-fl-71-bin.000001 | 137 | Query      |         1 |          137 | use `test`; insert into j2 (a) values (3)  |     
   | third-fl-71-bin.000001 | 201 | Query      |         1 |          201 | use `test`; insert into j2 (a) values (9)  |     
   | third-fl-71-bin.000001 | 265 | Query      |         1 |          265 | use `test`; delete from j2 where a=3       |     
   +------------------------+-----+------------+-----------+--------------+--------------------------------------------+     
   5 rows in set (0.00 sec)


تو جدول بالا می بینی که فیلدی با نام Event_type داریم.

کافیه برنامه شما این بانک رو پیمایش کنه و فیلد های مربوطه رو برداره و در آخر، این بانک لاگ (که یک فایل مجزاست) رو reset (خالی) کنه.

فیلد هایی هم که انتخاب کرده، می تونه تو یک فایل sql بنویسه یا به سرور بفرسته.

ممنون میشم کد برنامه ای که چنین کاری رو می کرد، به احترام دوستانی که پاسخت رو دادند، اینجا بذاری :)

موفق باشید.

----------


## tabib_m

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

----------


## oxygenws

عزیزم، لینکش رو دادم دیگه، بخونش :)
یک نوع لاگ گیری از فعالیت های سرور MySQL.
می تونی محدود به لاگ گیری از یک یا چند بانک بکنیش.
می تونی بین لاگ های گرفته شده پیمایش کنی و تمام کوئری هایی که به سرور ارسال شده است رو ببینی و یه حورایی شبیه کوئری نوشتن برای یک بانک، برای لاگ ها کوئری بنویسی و نتیجه جدول خروجی رو ببینی. (مثل جدول بالا که نوشتم)

----------


## Achchan

> First solution: Add a timestamp or date column to your table.So you can select only the rows after the max(date_column) on server,and transfer them.But you will need tigger for updating this column on local server and this is not available till mysql 5.0.x.



Have you read that? I think this is the best solution due to your experience(sorry but I guess according to your previous posts   :چشمک:  ). By the way,Have you tried to find something about Replication in Mysql?
-Good luck and feel free to mail me: baronc_rampantc@yahoo.ca

----------


## oxygenws

آچان، شما هم ظاهرا پست های دیگه رو نمی خونید :)
ایشون می خواد تغییرات نیز اعمال بشه، فقط عمل افزودن انجام نمی شه.
حالا فرض کنید این تغییر با "حذف" یک رکورد باشه، اونوقت این روش شما *هیچ* سودی نداره.

----------


## Achchan

Sorry I didn't noticed *Delete* records is needed.

----------


## tabib_m

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

البته یه مسئله ای هم برام پیش اومد. آیا اگه توی یک فایل پی اچ پی چند تا کوری داشته باشیم و مثلا دهمی اونها ارور بده ، آیا اون کوری های قبلی انجام شده اند یا این که پی اچ پی اول ارور ها رو تشخیص میده و در صورتی که هیچ اشکالی وجود نداشته باشه اونوقت تمام فایل انجام میشه؟ 

امیدوارم منظورم رو فهمیده باشید.

----------


## oxygenws

:) اگر رکوردی حذف بشه چی؟ :)
مطلبی که من نوشتم رو بخون و الکی دور خودت نگرد!!

----------


## tabib_m

بابا من که عرض کردم این کار رو فقط برای عمل اینسرت انجام میدم ،اونوقت اینجوری تمامی آیدی ها مشابه میشن اونوقت اگه قرار بشه رکوردی حذف یا ویرایش بشه رکورد اشتباهی روی هاست حذف نمیشه (به خاطر آیدیهای مطابق) همین ، اگه اشتباه میکنم بگید.

----------

