PDA

View Full Version : شماره نامه



www2006
یک شنبه 01 بهمن 1385, 20:07 عصر
سلام
فرض کنید یک سیستم نامه نگاری داریم که کاربران برای ارسال نامه خود به یک شماره نامه نیاز دارند ...
برای دادن شماره نامه منحصر بفرد برای هر نامه ( که هر کاربر درخواست آن را به سرور میدهد و سرور شماره را تولید کرده و برای کلاینت ارسال میکند) چه راهی پیشنهاد میکنید ؟

منظورم اینه که این فیلد ( احتمالا bigint ) رو تو کدوم یکی از تیبلهای دیتابیس باید قرار بدم ..

با تشکر ..

dkhatibi
یک شنبه 01 بهمن 1385, 20:32 عصر
تیبلهای شما چگونه است؟
مثلا تیبلی که یوزر را چک می کنه و یا به درخواستها رسیدگی می کنه.
شاید هم یک تیبل مجزا بهتر باشه!

www2006
یک شنبه 01 بهمن 1385, 21:40 عصر
تیبلهای شما چگونه است؟
مثلا تیبلی که یوزر را چک می کنه و یا به درخواستها رسیدگی می کنه.
شاید هم یک تیبل مجزا بهتر باشه!

سه تا تیبل دارم :
یکی اطلاعات کاربران ، یکی برای گروههای کاری و یکی هم برای نامه ها ...
من فکر میکنم اگه تو تیبل نامه ها یک فیلد AutoInc بعنوان شماره نامه در نظر بگیرم مشکل حل بشه ..
درسته ؟

www2006
یک شنبه 01 بهمن 1385, 22:49 عصر
البته مشکلی که در این صورت بوجود میاد اینه فرستنده ی نامه از شماره ی نامه ای که فرستاده خبر نداره ..
(برای پیگیریهای بعدی این شماره رو لازم داره ) ..

راه استاندارد تری وجود نداره ؟؟

Valadi
یک شنبه 01 بهمن 1385, 23:25 عصر
البته مشکلی که در این صورت بوجود میاد اینه فرستنده ی نامه از شماره ی نامه ای که فرستاده خبر نداره ..
(برای پیگیریهای بعدی این شماره رو لازم داره ) ..

راه استاندارد تری وجود نداره ؟؟

دوست عزیز چرا راه استانداری وجود نداره البته که داره اگر شما اطلاعاتی در سیستم دبیرخانه داشته باشید تا حدود می دونید باید چه کار کنید .
در سیستم دبیرخانه یک شماره وجود داره که این شماره دو حالت داره
1- فرستاده
2 - دریافتی
با توجه به دفاتر اندیکاتور دبیر خانه فعلی بازار


و اما برای شماره نامه شما می تونید موقعی که فرم لود میشه (البته دوستان هم اشاره به این موضوع داشتند) از این کد استفاده کنی :

Table1.Fields[0].asinteger:=Table1.RecordCount+1

این کد هر موقع که فرم ثبت اطلاعات نامه باز میشه یک عدد به شما می ده که شما می تونید بعنوان شماره نامه تلقی کنید


اگر هم کمکی در زمینه خواستی ما در خدمتیم

www2006
دوشنبه 02 بهمن 1385, 19:49 عصر
اگر شما اطلاعاتی در سیستم دبیرخانه داشته باشید تا حدود می دونید باید چه کار کنید .
در سیستم دبیرخانه یک شماره وجود داره که این شماره دو حالت داره
1- فرستاده
2 - دریافتی
با توجه به دفاتر اندیکاتور دبیر خانه فعلی بازار
تا حدودی (با یه تحقیق سرپایی) یه چیزایی دستم اومده بود ..



و اما برای شماره نامه شما می تونید موقعی که فرم لود میشه (البته دوستان هم اشاره به این موضوع داشتند) از این کد استفاده کنی :

Table1.Fields[0].asinteger:=Table1.RecordCount+1

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

1- اگر دو یا چند کاربر دقیقا همزمان فرم مربوطه به تایپ نامه را باز کنند احتمالا یک شماره یکسان خواهند داشت ( البته این مطلبو بر اساس ته مونده های اطلاعات مغزم از مبحث نواحی بحرانی که تو درس سیستم عامل داشتیم میگم ).. دقیقا به همین دلیل بود که من میخواستم از یک فیلد AutoInc استفاده کنم .

2- اگه یه کاربر فرم مربوط به ارسال نامه را باز کرد (وشمارنده یک واحد اضافه شد) و از ارسال نامه پشیمون شد عملا یکی از شماره های مربوط به نامه ها بدون دلیل مصرف شده . پس اگه جداگانه (مثلا توسط یک Button ) شماره نامه بگیره فکر میکنم بهتر باشه .. درسته ؟


آقا این راه همین الان به فکرم رسید :
وقتی کاربر درخواست شماره نامه داد ، ما یه Record خالی تو جدول Insert کنیم و شماره ای که از اضافه شدن فیلد "Lid " حاصل میشود (Lid همون فیلد AutoInc است) را برای کاربر ارسال کنیم .. حالا وقتی کاربر نامه را ارسال کرد ، نامه را در همین Record ( که مربوط به همین کاربر هست) اضافه کنیم ..

به نظر شما عملیه ..؟

FSarab
دوشنبه 02 بهمن 1385, 20:24 عصر
شما می خواهید یک شماره منحصر بفرد بر اساس یک فرمول خاصی تولید کنید
فیلد شما می تواند از نوع varchar باشد
ولی مسله اینجا مشکل همزمانی است ممکن است چند کاربر همزمان یک شماره دریافت کنند

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
{تولید شماره جدید}
COMMIT TRANSACTION
SET TRANSACTION ISOLATION LEVEL READ COMMITTED

Valadi
دوشنبه 02 بهمن 1385, 20:49 عصر
تا حدودی (با یه تحقیق سرپایی) یه چیزایی دستم اومده بود ..

ببینید نامه از طریق کاربرهای مختلف تو زمانهای مختلف تنظیم میشه ... این راهی که شما گفتید و این مساله ای که من اشاره کردم (احتمالا) این مشکلات را خواهد داشت :

1- اگر دو یا چند کاربر دقیقا همزمان فرم مربوطه به تایپ نامه را باز کنند احتمالا یک شماره یکسان خواهند داشت ( البته این مطلبو بر اساس ته مونده های اطلاعات مغزم از مبحث نواحی بحرانی که تو درس سیستم عامل داشتیم میگم ).. دقیقا به همین دلیل بود که من میخواستم از یک فیلد AutoInc استفاده کنم .

2- اگه یه کاربر فرم مربوط به ارسال نامه را باز کرد (وشمارنده یک واحد اضافه شد) و از ارسال نامه پشیمون شد عملا یکی از شماره های مربوط به نامه ها بدون دلیل مصرف شده . پس اگه جداگانه (مثلا توسط یک Button ) شماره نامه بگیره فکر میکنم بهتر باشه .. درسته ؟


آقا این راه همین الان به فکرم رسید :
وقتی کاربر درخواست شماره نامه داد ، ما یه Record خالی تو جدول Insert کنیم و شماره ای که از اضافه شدن فیلد "Lid " حاصل میشود (Lid همون فیلد AutoInc است) را برای کاربر ارسال کنیم .. حالا وقتی کاربر نامه را ارسال کرد ، نامه را در همین Record ( که مربوط به همین کاربر هست) اضافه کنیم ..

به نظر شما عملیه ..؟

فکر بدی نیست اگر این کار را می کنید باید شماره نامه بعد تمام پر کردن فلید ها باشه که اگر خواست نامه را ثبت نکنه مشکلی نباشه

www2006
دوشنبه 02 بهمن 1385, 22:12 عصر
امتحانش میکنم و نتیجه رو اعلام میکنم ..

ehsane
دوشنبه 02 بهمن 1385, 23:21 عصر
دوست عزیز فکر کنم منظور ایشان اینست که هر کسی بتواند در هر لحظه یک رکورد را در بانک ذخیره کند و شماره تولید شده توسط AutoInc توسط هر فرد مشخص باشد. من هم همین مشکل را دارم ، بنظرم باید یک برنامه در سرور نوشته شود و کار مدیریت این درخواست ها را بر عهده بگیرد و با توجه به هر درخواست شماره تولید شده را به همان کاربر برگرداند

arshia_
چهارشنبه 04 بهمن 1385, 07:57 صبح
باید در هنگام ذخیره نمودن نامه توسط کاربر مقدار عددی را دریافت کنی و ذخیره نمایی
اینطوری احتمال شماره تکراری کم می شود
مخصوصا اگر از auto number استفاده کنی
با این روش در بدترین حالت دو کاربر باید در کمتر از یک هزارم ثانیه با هم درخواست ذخیره بدهند که این امر بعید به نظر می رسد

darvishiali
پنج شنبه 05 بهمن 1385, 00:17 صبح
سلام؛

اولا باید بگم استفاده از TRANSACTION نباید در یک بازه طولانی انجام بشه (حتی در حدود یک ثانیه!) مخصوصا اگه تعداد Client ها زیاد باشن.

ثانیا اگه یه رکورد توی Table اضافه کنیم و بعد بخوایم Update کنیم چندتا مشکل داره مثلا اگه برنامه Crash بشه (مثلا در اثر خرابی سیستم یا قطع برق!)، یه رکورد بدون محتوا توی جدول باقی می مونه!

در ضمن، چون SQL Server داره Auto Increment رو پشتیبانی می کنه، هیچوقت نمیشه که دو رکورد با یک آیدنتیتی ذخیره بشن، حتی اگه هر دو با اختلاف زمانی یک میلیاردم ثانیه با هم بخوان ثبت بشن!


به نظر من بهترین راه حل اینه که تمام عملیات تایپ و اصلاح نامه انجام بشه و درنهایت وقتی که ذخیره شد، شماره رو برگردونه. (برای فیلد آیدنتیتی(Auto Increment) در SQL Server اینکار با SELECT @@IDENTITY امکان پذیره)

باز هم راه حل داره، اگه این به دردت نخورد، دوباره پیغام بذار. مرسی!

Navid7h
پنج شنبه 05 بهمن 1385, 01:12 صبح
سلام؛

اولا باید بگم استفاده از TRANSACTION نباید در یک بازه طولانی انجام بشه (حتی در حدود یک ثانیه!) مخصوصا اگه تعداد Client ها زیاد باشن.

ثانیا اگه یه رکورد توی Table اضافه کنیم و بعد بخوایم Update کنیم چندتا مشکل داره مثلا اگه برنامه Crash بشه (مثلا در اثر خرابی سیستم یا قطع برق!)، یه رکورد بدون محتوا توی جدول باقی می مونه!

در ضمن، چون SQL Server داره Auto Increment رو پشتیبانی می کنه، هیچوقت نمیشه که دو رکورد با یک آیدنتیتی ذخیره بشن، حتی اگه هر دو با اختلاف زمانی یک میلیاردم ثانیه با هم بخوان ثبت بشن!


به نظر من بهترین راه حل اینه که تمام عملیات تایپ و اصلاح نامه انجام بشه و درنهایت وقتی که ذخیره شد، شماره رو برگردونه. (برای فیلد آیدنتیتی(Auto Increment) در SQL Server اینکار با SELECT @@IDENTITY امکان پذیره)

باز هم راه حل داره، اگه این به دردت نخورد، دوباره پیغام بذار. مرسی!



من یک همچنین مشکلی رو با روش پیشنهادی شما حل کردمک
حالا اگه میشه شما هم راههای دیگه رو بگید.

متشکرم

www2006
پنج شنبه 05 بهمن 1385, 20:23 عصر
سلام؛

اولا باید بگم استفاده از TRANSACTION نباید در یک بازه طولانی انجام بشه (حتی در حدود یک ثانیه!) مخصوصا اگه تعداد Client ها زیاد باشن.

ثانیا اگه یه رکورد توی Table اضافه کنیم و بعد بخوایم Update کنیم چندتا مشکل داره مثلا اگه برنامه Crash بشه (مثلا در اثر خرابی سیستم یا قطع برق!)، یه رکورد بدون محتوا توی جدول باقی می مونه!

در ضمن، چون SQL Server داره Auto Increment رو پشتیبانی می کنه، هیچوقت نمیشه که دو رکورد با یک آیدنتیتی ذخیره بشن، حتی اگه هر دو با اختلاف زمانی یک میلیاردم ثانیه با هم بخوان ثبت بشن!


1- درباره Transaction : من تا حالا از Transaction استفاده نکردم پس اطلاعات کاربردی به درد بخوری دربارش ندارم .. اگه لطف کنید و بیشتر درباره ایجاد Transaction و مفاهیم مربوطه توضیح بدید ممنون میشم .
(انشاالله بتونم در برنامه های بعدی ازش استفاده کنم)

2- اینکه شما گفتی :


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

3-


(برای فیلد آیدنتیتی(Auto Increment) در SQL Server اینکار با SELECT @@IDENTITY امکان پذیره)
من با یک کویری آخرین شماره ای که بنام کاربر درخواست دهنده در جدول موجود است را برمیگردانم و فکر میکنم درست عمل کنه...
(به بیان ساده : منظور شما را متوجه نشدم )

با تشکر ..

Mah6447
شنبه 07 بهمن 1385, 13:25 عصر
یک مشکل دیگری که در پاسخ های اساتید می باشد این است که در سیستم های نامه نگاری نیاز است که شروع هر سال شماره نامه ها از 1 شروع شود حال اینکه در فیلدهایی از نوع Auto Increment این عمل به نظر غیر ممکن می باشد .

ehsane
یک شنبه 08 بهمن 1385, 09:00 صبح
[quet]
من با یک کویری آخرین شماره ای که بنام کاربر درخواست دهنده در جدول موجود است را برمیگردانم و فکر میکنم درست عمل کنه...
[quet/]
دوست عزیز اگر تعداد رکوردهای شما زیاد باشد مثلا 20000 یا 50000 آنوقت هر دفعه شما با کوئری این تعداد را در حافظه لود می کنید. مشکل سرعت برای شما پیش نمی آد

Valadi
یک شنبه 08 بهمن 1385, 09:15 صبح
اکر دیتا بیس اکسس باشد بعد از 150000 فیلد سرعت کم می شود و طبیعتا سرعت برنامه هم کم می شود

Valadi
یک شنبه 08 بهمن 1385, 09:19 صبح
یک مشکل دیگری که در پاسخ های اساتید می باشد این است که در سیستم های نامه نگاری نیاز است که شروع هر سال شماره نامه ها از 1 شروع شود حال اینکه در فیلدهایی از نوع Auto Increment این عمل به نظر غیر ممکن می باشد .

اینکه مشکلی نیست خیلی راحت می شه این مسئله را حل کرد اما مسیر یک مقدار پیچیده است

www2006
یک شنبه 08 بهمن 1385, 20:16 عصر
اکر دیتا بیس اکسس باشد بعد از 150000 فیلد سرعت کم می شود و طبیعتا سرعت برنامه هم کم می شود
بانک من SQLServer است ... فکر نمیکنم مشکل پیش بیاد
البته کویری گرفتن اجتناب نپذیره ( منظورم این مورد نیست ، کلا تو برنامه از کویری های مختلفی استفاده میکنم ..



اینکه مشکلی نیست خیلی راحت می شه این مسئله را حل کرد اما مسیر یک مقدار پیچیده استولی تا اونجایی که من میدونم فیلد Identity را نمیشه به هیچ وجه دستکاری کرد ...

Valadi
دوشنبه 09 بهمن 1385, 10:11 صبح
جناب www2006 این از یک راه دیگری است و ربطی هم به فیلد Identity ندارد از همین ترفند در نرم افزارهای حسابداری که قابلیت تعریف سال کاری دارد استفاده شده است

www2006
دوشنبه 09 بهمن 1385, 12:18 عصر
جناب www2006 این از یک راه دیگری است و ربطی هم به فیلد Identity ندارد از همین ترفند در نرم افزارهای حسابداری که قابلیت تعریف سال کاری دارد استفاده شده است
میشه بیشتر توضیح بدین ...
منظورم تعریف سال کاری و مفاهیم احتمالی مرتبط با اونه ..

ehsane
سه شنبه 10 بهمن 1385, 18:40 عصر
دوست عزیز اگه منظور شما از تغییر در فیلد Identity صفر کردن آن است شما میتوانید با استفاده از این دستور براحتی میتونید این کار رو را انجام بدید. قبلا دوستان به این موضوع اشاره کردند.
DBCC CHECKIDENT (table1, RESEED, 30)