একটি সাধারণ ব্যাংক স্কিমা লেখা: আমি কীভাবে আমার ব্যালেন্সগুলি তাদের লেনদেনের ইতিহাসের সাথে সুসংগত রাখব?


57

আমি একটি সাধারণ ব্যাংক ডাটাবেসের জন্য স্কিমা লিখছি। এখানে মূল বৈশিষ্ট্যগুলি রয়েছে:

  • ডাটাবেস কোনও ব্যবহারকারীর এবং মুদ্রার বিপরীতে লেনদেন সংরক্ষণ করবে।
  • প্রতিটি ব্যবহারকারীর মুদ্রায় প্রতি ব্যালেন্স থাকে, সুতরাং প্রতিটি ব্যালেন্স কেবলমাত্র প্রদত্ত ব্যবহারকারী এবং মুদ্রার বিপরীতে সমস্ত লেনদেনের যোগফল।
  • ভারসাম্য নেতিবাচক হতে পারে না।

ব্যাংক অ্যাপ্লিকেশন কেবলমাত্র সঞ্চিত পদ্ধতির মাধ্যমে তার ডাটাবেসের সাথে যোগাযোগ করবে।

আমি আশা করি যে এই ডাটাবেসটি প্রতিদিন কয়েক লক্ষ নতুন লেনদেনের পাশাপাশি উচ্চতর মানের ক্রমে ভারসাম্য কোয়েরি গ্রহণ করবে। খুব দ্রুত ভারসাম্য বজায় রাখার জন্য আমার সেগুলি পূর্বনির্ধারিত করা দরকার। একই সময়ে, আমার গ্যারান্টি দেওয়া দরকার যে কোনও ভারসাম্য কখনও তার লেনদেনের ইতিহাসের সাথে বিরোধী হয় না।

আমার বিকল্পগুলি হ'ল:

  1. একটি পৃথক balancesটেবিল আছে এবং নিম্নলিখিতগুলির একটি করুন:

    1. উভয় transactionsএবং balancesটেবিল উভয় লেনদেন প্রয়োগ করুন । TRANSACTIONভারসাম্য এবং লেনদেন সবসময় সিঙ্ক থাকে তা নিশ্চিত করতে আমার সঞ্চিত পদ্ধতি স্তরটিতে যুক্তি ব্যবহার করুন। ( জ্যাক সমর্থিত ।)

    2. transactionsসারণীতে লেনদেন প্রয়োগ করুন এবং একটি ট্রিগার থাকুন যা balancesআমার জন্য লেনদেনের পরিমাণের সাথে টেবিল আপডেট করে ।

    3. balancesটেবিলটিতে লেনদেন প্রয়োগ করুন এবং একটি ট্রিগার থাকুন যা transactionsআমার জন্য লেনদেনের পরিমাণ সহ সারণীতে একটি নতুন এন্ট্রি যুক্ত করে ।

    সঞ্চিত পদ্ধতির বাইরে কোনও পরিবর্তন আনা যায় না তা নিশ্চিত করতে আমাকে সুরক্ষা-ভিত্তিক পদ্ধতির উপর নির্ভর করতে হবে। অন্যথায়, উদাহরণস্বরূপ, কিছু প্রক্রিয়া সরাসরি transactionsটেবিলের মধ্যে একটি লেনদেন সন্নিবেশ করতে পারে এবং স্কিমের আওতায় 1.3সম্পর্কিত ব্যালেন্স সিঙ্কের বাইরে চলে যাবে।

  2. balancesলেনদেন যথাযথভাবে একত্রিত করে এমন একটি সূচকযুক্ত দৃষ্টিভঙ্গি রাখুন । ভারসাম্য ইঞ্জিন তাদের লেনদেনের সাথে সামঞ্জস্য রাখতে গ্যারান্টিযুক্ত হয়, সুতরাং এটিকে গ্যারান্টি হিসাবে আমার সুরক্ষা ভিত্তিক পদ্ধতির উপর নির্ভর করতে হবে না। অন্যদিকে, আমি ভারসাম্যগুলি আর-অ-নেতিবাচক হতে পারি না, যেহেতু দর্শনগুলি - এমনকি সূচিযুক্ত দর্শনগুলি - CHECKসীমাবদ্ধতাও রাখতে পারে না । ( ডেনির সমর্থিত )

  3. transactionsএই লেনদেনটি কার্যকর হওয়ার পরে কার্যকর ভারসাম্য রক্ষার জন্য কেবল একটি টেবিল আছে তবে অতিরিক্ত কলাম সহ। সুতরাং, ব্যবহারকারীর জন্য সর্বশেষ লেনদেনের রেকর্ড এবং মুদ্রায় তাদের বর্তমান ব্যালেন্সও রয়েছে। ( অ্যান্ড্রু নীচে প্রস্তাবিত ; গ্যারিক দ্বারা প্রস্তাবিত বৈকল্পিক ।)

আমি যখন প্রথম এই সমস্যার সমাধান করেছি, তখন আমি এই দুটি আলোচনা পড়েছি এবং বিকল্পের বিষয়ে সিদ্ধান্ত নিয়েছি 2। রেফারেন্সের জন্য, আপনি এটি এখানে একটি খালি-হাড় প্রয়োগ বাস্তবায়ন করতে পারেন ।

  • আপনি কি উচ্চ লোড প্রোফাইল দিয়ে এর মতো একটি ডেটাবেস ডিজাইন বা পরিচালনা করেছেন? আপনার এই সমস্যার সমাধান কী ছিল?

  • আপনি কি মনে করেন যে আমি সঠিক নকশার পছন্দটি করেছি? আমার কিছু মনে রাখা উচিত?

    উদাহরণস্বরূপ, আমি জানি transactionsটেবিলের স্কিমা পরিবর্তনগুলির জন্য আমার balancesভিউটি পুনর্নির্মাণের প্রয়োজন হবে । এমনকি যদি আমি ডাটাবেস ছোট রাখার জন্য লেনদেন সংরক্ষণ করি (যেমন তাদের অন্য কোথাও সরিয়ে নিয়ে সংক্ষিপ্ত লেনদেনের বদলে), প্রতিটি স্কিমা আপডেটের মাধ্যমে কয়েক মিলিয়ন লেনদেনের ভিউটি পুনর্নির্মাণ করা সম্ভবত প্রতিস্থাপনে উল্লেখযোগ্যভাবে আরও ডাউনটাইম বোঝাতে চাইবে।

  • যদি সূচকযুক্ত দৃশ্যটি যাওয়ার উপায় হয় তবে আমি কীভাবে গ্যারান্টি দিতে পারি যে কোনও ভারসাম্য নেতিবাচক নয়?


সংরক্ষণাগার লেনদেন:

সংরক্ষণাগার লেনদেন এবং আমি উপরে উল্লিখিত "সারাংশ লেনদেনগুলি" সম্পর্কে কিছুটা বিশদভাবে বলি। প্রথমত, নিয়মিত সংরক্ষণাগারটি এই জাতীয় উচ্চ-লোড সিস্টেমে প্রয়োজনীয়তা হবে a পুরানো লেনদেন অন্য কোথাও স্থানান্তরিত করার সময় আমি ভারসাম্য এবং তাদের লেনদেনের ইতিহাসের মধ্যে ধারাবাহিকতা বজায় রাখতে চাই। এটি করার জন্য আমি আর্কাইভ লেনদেনের প্রতিটি ব্যাচ তাদের ব্যবহারকারী এবং মুদ্রার পরিমাণের সংক্ষিপ্তসার সহ প্রতিস্থাপন করব।

সুতরাং, উদাহরণস্বরূপ, লেনদেনের এই তালিকা:

user_id    currency_id      amount    is_summary
------------------------------------------------
      3              1       10.60             0
      3              1      -55.00             0
      3              1      -12.12             0

দূরে সংরক্ষণাগারযুক্ত এবং এটি দিয়ে প্রতিস্থাপন করা হয়:

user_id    currency_id      amount    is_summary
------------------------------------------------
      3              1      -56.52             1

এইভাবে, সংরক্ষণাগারভুক্ত লেনদেনের সাথে ভারসাম্য একটি সম্পূর্ণ এবং ধারাবাহিক লেনদেনের ইতিহাস বজায় রাখে।


1
আপনি যদি বিকল্প 2 পছন্দ করেন (যা আমি পরিষ্কার বলে মনে করি) তবে কীভাবে "বস্তুগত দৃষ্টিভঙ্গি" কার্যকরভাবে প্রয়োগ করতে হয় সে জন্য pgcon.org/2008/schedule/attachments/… দেখুন । বিকল্প 1 এর জন্য, হানস এর 11 তম অধ্যায় এবং ডাটাবেস পেশাদারদের জন্য কোপ্পেলারস প্রয়োগিত গণিতের (শিরোনাম সম্পর্কে চিন্তা করবেন না) কীভাবে দক্ষতার সাথে "সংক্রমণের সীমাবদ্ধতা" প্রয়োগ করা যায় সে সম্পর্কে ধারণা পেতে সহায়তা করবে। প্রথম লিঙ্কটি পোস্টগ্রেএসকিউএল এবং দ্বিতীয়টি ওরাকল এর জন্য, তবে কৌশলগুলি কোনও যুক্তিসঙ্গত ডাটাবেস সিস্টেমের জন্য কাজ করা উচিত।
জেপি

তত্ত্বত আপনি # 3 করতে চান। "চলমান ভারসাম্য" করার সঠিক উপায় হ'ল প্রতিটি লেনদেনের জন্য ভারসাম্য নির্ধারণ করা। নিশ্চিত হয়ে নিন যে আপনি কোনও সিরিয়াল আইডি (পছন্দসই) বা টাইমস্ট্যাম্পের মাধ্যমে নিশ্চিতভাবে লেনদেনগুলি অর্ডার করতে পারবেন। আপনার সত্যিকারের চলমান ভারসাম্য "গণনা" করার কথা নয়।
pbreitenbach

উত্তর:


15

আমি অ্যাকাউন্টিংয়ের সাথে পরিচিত নই, তবে ইনভেন্টরি-ধরণের পরিবেশে কিছু অনুরূপ সমস্যা সমাধান করেছি। আমি লেনদেনের সাথে একই সারিতে চলমান মোট সঞ্চয় করি। আমি সীমাবদ্ধতাগুলি ব্যবহার করছি, যাতে আমার ডেটা উচ্চ সম্মতিতে এমনকি কখনও ভুল না হয়। আমি নিম্নলিখিত সমাধানটি আবার ২০০৯ সালে লিখেছি :

চলমান মোটের গণনা করা কুখ্যাতভাবে ধীর, আপনি এটি কর্সার দিয়ে বা ত্রিভুজাকার জোড় দিয়েই করেন না কেন। এটি একটি সংজ্ঞায়িত করা, কলামে চলমান মোট সঞ্চয় করার জন্য খুব লোভনীয়, বিশেষত যদি আপনি প্রায়শই এটি নির্বাচন করেন। যাইহোক, যথারীতি আপনি যখন অস্বীকৃতি জানাতে থাকেন তখন আপনার অস্বীকৃত ডেটার অখণ্ডতার গ্যারান্টি দেওয়া দরকার। ভাগ্যক্রমে, আপনি প্রতিবন্ধকতা সহ মোট চলমান অখণ্ডতার গ্যারান্টি দিতে পারেন - যতক্ষণ না আপনার সমস্ত সীমাবদ্ধতা বিশ্বাসযোগ্য ততক্ষণ আপনার সমস্ত চলমান মোট সঠিক correct এছাড়াও এইভাবে আপনি সহজেই নিশ্চিত করতে পারেন যে বর্তমান ভারসাম্য (চলমান মোট) কখনই নেতিবাচক নয় - অন্যান্য পদ্ধতি দ্বারা প্রয়োগ করাও খুব ধীর হতে পারে। নিম্নলিখিত লিপিটি কৌশলটি দেখায়।

CREATE TABLE Data.Inventory(InventoryID INT NOT NULL IDENTITY,
  ItemID INT NOT NULL,
  ChangeDate DATETIME NOT NULL,
  ChangeQty INT NOT NULL,
  TotalQty INT NOT NULL,
  PreviousChangeDate DATETIME NULL,
  PreviousTotalQty INT NULL,
  CONSTRAINT PK_Inventory PRIMARY KEY(ItemID, ChangeDate),
  CONSTRAINT UNQ_Inventory UNIQUE(ItemID, ChangeDate, TotalQty),
  CONSTRAINT UNQ_Inventory_Previous_Columns 
     UNIQUE(ItemID, PreviousChangeDate, PreviousTotalQty),
  CONSTRAINT FK_Inventory_Self FOREIGN KEY(ItemID, PreviousChangeDate, PreviousTotalQty)
    REFERENCES Data.Inventory(ItemID, ChangeDate, TotalQty),
  CONSTRAINT CHK_Inventory_Valid_TotalQty CHECK(
         TotalQty >= 0 
     AND (TotalQty = COALESCE(PreviousTotalQty, 0) + ChangeQty)
  ),
  CONSTRAINT CHK_Inventory_Valid_Dates_Sequence CHECK(PreviousChangeDate < ChangeDate),
  CONSTRAINT CHK_Inventory_Valid_Previous_Columns CHECK(
        (PreviousChangeDate IS NULL AND PreviousTotalQty IS NULL)
     OR (PreviousChangeDate IS NOT NULL AND PreviousTotalQty IS NOT NULL)
  )
);

-- beginning of inventory for item 1
INSERT INTO Data.Inventory(ItemID,
  ChangeDate,
  ChangeQty,
  TotalQty,
  PreviousChangeDate,
  PreviousTotalQty)
VALUES(1, '20090101', 10, 10, NULL, NULL);

-- cannot begin the inventory for the second time for the same item 1
INSERT INTO Data.Inventory(ItemID,
  ChangeDate,
  ChangeQty,
  TotalQty,
  PreviousChangeDate,
  PreviousTotalQty)
VALUES(1, '20090102', 10, 10, NULL, NULL);


Msg 2627, Level 14, State 1, Line 10

Violation of UNIQUE KEY constraint 'UNQ_Inventory_Previous_Columns'. 
Cannot insert duplicate key in object 'Data.Inventory'.

The statement has been terminated.


-- add more
DECLARE @ChangeQty INT;
SET @ChangeQty = 5;

INSERT INTO Data.Inventory(ItemID,
  ChangeDate,
  ChangeQty,
  TotalQty,
  PreviousChangeDate,
  PreviousTotalQty)

SELECT TOP 1 ItemID, '20090103', @ChangeQty, TotalQty + @ChangeQty, ChangeDate, TotalQty
  FROM Data.Inventory
  WHERE ItemID = 1
  ORDER BY ChangeDate DESC;

SET @ChangeQty = 3;

INSERT INTO Data.Inventory(ItemID,
  ChangeDate,
  ChangeQty,
  TotalQty,
  PreviousChangeDate,
  PreviousTotalQty)

SELECT TOP 1 ItemID, '20090104', @ChangeQty, TotalQty + @ChangeQty, ChangeDate, TotalQty
  FROM Data.Inventory
  WHERE ItemID = 1
  ORDER BY ChangeDate DESC;

SET @ChangeQty = -4;

INSERT INTO Data.Inventory(ItemID,
  ChangeDate,
  ChangeQty,
  TotalQty,
  PreviousChangeDate,
  PreviousTotalQty)

SELECT TOP 1 ItemID, '20090105', @ChangeQty, TotalQty + @ChangeQty, ChangeDate, TotalQty
  FROM Data.Inventory
  WHERE ItemID = 1
  ORDER BY ChangeDate DESC;

-- try to violate chronological order
SET @ChangeQty = 5;

INSERT INTO Data.Inventory(ItemID,
  ChangeDate,
  ChangeQty,
  TotalQty,
  PreviousChangeDate,
  PreviousTotalQty)

SELECT TOP 1 ItemID, '20081231', @ChangeQty, TotalQty + @ChangeQty, ChangeDate, TotalQty
  FROM Data.Inventory
  WHERE ItemID = 1
  ORDER BY ChangeDate DESC;

Msg 547, Level 16, State 0, Line 4

The INSERT statement conflicted with the CHECK constraint 
"CHK_Inventory_Valid_Dates_Sequence". 
The conflict occurred in database "Test", table "Data.Inventory".

The statement has been terminated.

SELECT ChangeDate,
  ChangeQty,
  TotalQty,
  PreviousChangeDate,
  PreviousTotalQty
FROM Data.Inventory ORDER BY ChangeDate;

ChangeDate              ChangeQty   TotalQty    PreviousChangeDate      PreviousTotalQty
----------------------- ----------- ----------- ----------------------- -----
2009-01-01 00:00:00.000 10          10          NULL                    NULL
2009-01-03 00:00:00.000 5           15          2009-01-01 00:00:00.000 10
2009-01-04 00:00:00.000 3           18          2009-01-03 00:00:00.000 15
2009-01-05 00:00:00.000 -4          14          2009-01-04 00:00:00.000 18


-- try to change a single row, all updates must fail
UPDATE Data.Inventory SET ChangeQty = ChangeQty + 2 WHERE InventoryID = 3;
UPDATE Data.Inventory SET TotalQty = TotalQty + 2 WHERE InventoryID = 3;

-- try to delete not the last row, all deletes must fail
DELETE FROM Data.Inventory WHERE InventoryID = 1;
DELETE FROM Data.Inventory WHERE InventoryID = 3;

-- the right way to update
DECLARE @IncreaseQty INT;

SET @IncreaseQty = 2;

UPDATE Data.Inventory 
SET 
     ChangeQty = ChangeQty 
   + CASE 
        WHEN ItemID = 1 AND ChangeDate = '20090103' 
        THEN @IncreaseQty 
        ELSE 0 
     END,
  TotalQty = TotalQty + @IncreaseQty,
  PreviousTotalQty = PreviousTotalQty + 
     CASE 
        WHEN ItemID = 1 AND ChangeDate = '20090103' 
        THEN 0 
        ELSE @IncreaseQty 
     END
WHERE ItemID = 1 AND ChangeDate >= '20090103';

SELECT ChangeDate,
  ChangeQty,
  TotalQty,
  PreviousChangeDate,
  PreviousTotalQty
FROM Data.Inventory ORDER BY ChangeDate;

ChangeDate              ChangeQty   TotalQty    PreviousChangeDate      PreviousTotalQty
----------------------- ----------- ----------- ----------------------- ----------------
2009-01-01 00:00:00.000 10          10          NULL                    NULL
2009-01-03 00:00:00.000 7           17          2009-01-01 00:00:00.000 10
2009-01-04 00:00:00.000 3           20          2009-01-03 00:00:00.000 17
2009-01-05 00:00:00.000 -4          16          2009-01-04 00:00:00.000 20

14

গ্রাহকদের 0 টির চেয়ে কম ভারসাম্য না রাখতে দেওয়া হ'ল একটি ব্যবসায়িক নিয়ম (যা ওভার ড্রাফ্টের মতো জিনিসের জন্য ফিগুলি ব্যাংকগুলি কীভাবে সবচেয়ে বেশি অর্থ উপার্জন করে তা দ্রুত পরিবর্তিত হবে)। সারিগুলি লেনদেনের ইতিহাসে সন্নিবেশ করা হলে আপনি অ্যাপ্লিকেশন প্রসেসিংয়ে এটি হ্যান্ডেল করতে চাইবেন। বিশেষত যেহেতু আপনি কিছু গ্রাহককে ওভারড্রাফট সুরক্ষা এবং কিছুকে চার্জড ফি এবং কিছুকে নেতিবাচক পরিমাণে প্রবেশের অনুমতি না দিয়ে শেষ করতে পারেন।

এখন পর্যন্ত আমি পছন্দ করি আপনি কোথায় যাচ্ছেন, তবে এটি যদি কোনও প্রকৃত প্রকল্পের জন্য হয় (স্কুল নয়) তবে ব্যবসায়ের নিয়ম ইত্যাদির মধ্যে অনেক চিন্তাভাবনা করা দরকার Once এবং দৌড়াতে আবার ডিজাইনের জন্য খুব বেশি জায়গা নেই কারণ লোকেরা তাদের অর্থ অ্যাক্সেস নিয়ে খুব নির্দিষ্ট আইন রয়েছে।


1
আমি দেখতে পাচ্ছি যে কেন ভারসাম্য সীমাবদ্ধতা আসলে ব্যবসায়ের নিয়ম হওয়া উচিত। ডাটাবেসটি কেবল একটি লেনদেনের পরিষেবা সরবরাহ করে এবং এটি ব্যবহার করে কী করবেন তা সিদ্ধান্ত নেওয়ার উপর নির্ভর করে ব্যবহারকারীরা।
নিক চাম্মাস

দুটি সারণী ব্যবহার করে বিকাশকারীদের ব্যবসার যুক্তি পরিবর্তন বা বাস্তবায়নে আরও নমনীয়তা অর্জনে জ্যাকের এই মন্তব্য সম্পর্কে আপনার কী ধারণা? এছাড়াও, আপনার উদ্বেগিত দৃষ্টিভঙ্গিগুলির সাথে কোনও সরাসরি অভিজ্ঞতা আছে যা এই উদ্বেগগুলিকে বৈধতা দেয় বা চ্যালেঞ্জ করে ?
নিক চ্যামাস

1
আমি বলব না যে দুটি টেবিল থাকা আপনাকে নমনীয়তা সরিয়ে দেয় ব্যবসায়ের যুক্তি বাস্তবায়ন করে। এটি আপনাকে ডেটা সংরক্ষণাগার করার ক্ষেত্রে আরও নমনীয়তা দেয়। তবে একটি ব্যাংক হিসাবে (কমপক্ষে মার্কিন যুক্তরাষ্ট্রে) আপনি এমন আইন পেয়েছেন যা বলে যে আপনার কতটা তথ্য রাখতে হবে। উপরের দৃশ্যের সাথে পারফরম্যান্সটি কীভাবে দেখায় তা পরীক্ষা করতে চাইবেন, সেই সাথে এটিও বিবেচনায় নিতে হবে যে আপনার যদি একটি সূচীকৃত ভিউ থাকে তবে আপনি অন্তর্নিহিত টেবিলগুলির স্কিমা পরিবর্তন করতে পারবেন না। ভেবে দেখার মতো আরও একটি বিষয়।
mrdenny

নিবন্ধে উল্লিখিত সমস্ত আইটেমগুলি কোনও সূচকযুক্ত ভিউ ব্যবহার করার বিষয়ে বৈধ উদ্বেগ।
mrdenny

1
স্পষ্ট করার জন্য: আইএমও একটি লেনদেনের এআইপি ব্যবসায়িক যুক্তি বাস্তবায়নে আরও নমনীয়তা দেয় (দুটি টেবিল নেই)। এই ক্ষেত্রে আমি দুটি সারণীর পক্ষেও থাকব (কমপক্ষে আমাদের কাছে এখনও পর্যন্ত তথ্য দেওয়া আছে) কারণ সূচকযুক্ত দৃষ্টিভঙ্গির সাথে প্রস্তাবিত ট্রেড-অফগুলি (যেমন ব্যালেন্স> 0 ব্যবসায় প্রয়োগের জন্য ডিআরআই ব্যবহার করতে পারবেন না) নিয়ম)
জ্যাক ডগলাস

13

বিবেচনা করার জন্য কিছুটা ভিন্ন পদ্ধতির (আপনার ২ য় বিকল্পের অনুরূপ ) কেবলমাত্র লেনদেনের টেবিল রাখা উচিত, এর সংজ্ঞা সহ:

CREATE TABLE Transaction (
      UserID              INT
    , CurrencyID          INT 
    , TransactionDate     DATETIME  
    , OpeningBalance      MONEY
    , TransactionAmount   MONEY
);

আপনি কোনও লেনদেন আইডি / অর্ডারও চাইতে পারেন, যাতে আপনি একই তারিখের সাথে দুটি লেনদেন পরিচালনা করতে পারেন এবং আপনার পুনরুদ্ধার ক্যোয়ারীটি উন্নত করতে পারেন।

বর্তমান ব্যালেন্সটি পেতে, আপনাকে যা করতে হবে তা হ'ল শেষ রেকর্ড।

শেষ রেকর্ড পাওয়ার পদ্ধতি :

/* For a single User/Currency */
Select TOP 1 *
FROM dbo.Transaction
WHERE UserID = 3 and CurrencyID = 1
ORDER By TransactionDate desc

/* For multiple records ie: to put into a view (which you might want to index) */
SELECT
    C.*
FROM
    (SELECT 
        *, 
        ROW_NUMBER() OVER (
           PARTITION BY UserID, CurrencyID 
           ORDER BY TransactionDate DESC
        ) AS rnBalance 
    FROM Transaction) C
WHERE
    C.rnBalance = 1
ORDER BY
    C.UserID, C.CurrencyID

কনস:

  • ক্রম বহির্ভূত কোনও লেনদেন সন্নিবেশ করার সময় (যেমন: কোনও সমস্যা সংশোধন করতে / ভুল সূচনার ভারসাম্য বজায় রাখতে), আপনাকে পরবর্তী সমস্ত লেনদেনের জন্য আপডেট ক্যাসকেডের প্রয়োজন হতে পারে।
  • একটি সঠিক ভারসাম্য বজায় রাখার জন্য ব্যবহারকারী / মুদ্রার জন্য লেনদেনের ক্রমিকায়ন করা দরকার।

    -- Example of getting the current balance and locking the 
    -- last record for that User/Currency.
    -- This lock will be freed after the Stored Procedure completes.
    SELECT TOP 1 @OldBalance = OpeningBalance + TransactionAmount  
    FROM dbo.Transaction with (rowlock, xlock)   
    WHERE UserID = 3 and CurrencyID = 1  
    ORDER By TransactionDate DESC;

পেশাদাররা:

  • আপনাকে আর দুটি পৃথক টেবিল বজায় রাখতে হবে না ...
  • আপনি সহজেই ভারসাম্যটি বৈধতা দিতে পারেন, এবং যখন ভারসাম্যটি সিঙ্কের বাইরে চলে যায় তখন লেনদেনের ইতিহাসটি স্ব নথিবদ্ধ হওয়ার সাথে সাথে তা ঠিকঠাক হয়ে গেলে ঠিক চিহ্নিত করতে পারেন।

সম্পাদনা করুন: বর্তমান ভারসাম্য পুনরুদ্ধার এবং কন হাইলাইট করার জন্য কিছু নমুনা প্রশ্ন (ধন্যবাদ @ জ্যাক ডগলাস)


3
SELECT TOP (1) ... ORDER BY TransactionDate DESCখুব এমনভাবে SQL সার্ভার ক্রমাগত লেনদেন টেবিল স্ক্যান করে না বাস্তবায়ন চতুর হতে হবে। অ্যালেক্স কুজনেটসভ একটি অনুরূপ নকশা সমস্যার সমাধান এখানে পোস্ট করেছেন যা এই উত্তরটির পুরোপুরি পরিপূরক করে।
নিক চ্যামাস

2
+1 আমি অনুরূপ পন্থা ব্যবহার করছি। বিটিডাব্লু, আমাদের খুব সাবধানতা অবলম্বন করা উচিত এবং আমাদের কোডটি সহবর্তী কাজের চাপের অধীনে সঠিকভাবে কাজ করে তা নিশ্চিত করা দরকার।
একে

12

এই দুটি আলোচনা পড়ার পরে, আমি বিকল্প 2 নিয়ে সিদ্ধান্ত নিয়েছি

এই আলোচনাগুলিও পড়েছি, আমি নিশ্চিত নই যে আপনি ডিআরআই সমাধানের বিষয়ে কেন সিদ্ধান্ত নিয়েছিলেন যে আপনি যে বিকল্পগুলি উল্লেখ করেছেন সেগুলির মধ্যে সবচেয়ে বুদ্ধিমান:

লেনদেন এবং ভারসাম্য সারণিতে উভয়কেই লেনদেন প্রয়োগ করুন। ভারসাম্য এবং লেনদেন সর্বদা সিঙ্কে রয়েছে তা নিশ্চিত করতে আমার সঞ্চিত পদ্ধতি স্তরটিতে ট্রান্সএक्शन লজিক ব্যবহার করুন।

আপনার ট্রানজেকশনাল API এর মাধ্যমে ডেটাতে সমস্ত অ্যাক্সেস সীমাবদ্ধ করার বিলাসিতা থাকলে এই ধরণের সমাধানের প্রচুর ব্যবহারিক সুবিধা রয়েছে benefits আপনি ডিআরআইয়ের খুব গুরুত্বপূর্ণ সুবিধাটি হারাবেন, এটি হ'ল ডেটাবেস দ্বারা সততা গ্যারান্টিযুক্ত, তবে পর্যাপ্ত জটিলতার কোনও মডেলটিতে এমন কিছু ব্যবসায়িক বিধি থাকবে যা ডিআরআই দ্বারা প্রয়োগ করা যায় না

আমি আপনার মডেলটিকে খুব বেশি বাঁক না করে ব্যবসায়ের নিয়মগুলি কার্যকর করার ক্ষেত্রে ডিআরআই ব্যবহার করার পরামর্শ দিচ্ছি:

এমনকি আমি লেনদেন সংরক্ষণাগারও রাখছি (যেমন এগুলি অন্য কোথাও স্থানান্তরিত করে এবং সংক্ষিপ্ত লেনদেনের সাথে তাদের প্রতিস্থাপন করে)

আপনি আপনার মডেলটিকে এভাবে দূষিত করার বিষয়টি বিবেচনা শুরু করার সাথে সাথেই আমি মনে করি আপনি যে অঞ্চলে প্রবর্তন করছেন তাতে ডিআরআইয়ের সুবিধা যে পরিমাণে বেড়েছে, আপনি সেই অঞ্চলে চলে যাচ্ছেন। উদাহরণস্বরূপ বিবেচনা করুন যে আপনার আর্কাইভ প্রক্রিয়ায় কোনও ত্রুটি তত্ত্বীয়ভাবে আপনার স্বর্ণের নিয়মের (যে ভারসাম্য সবসময় লেনদেনের যোগফলের সমান হয়) একটি ডিআরআই সমাধান সহ নীরবে ভাঙ্গতে পারে

এখানে আমি যেমন দেখছি তেমন লেনদেনের পদ্ধতির সুবিধার সংক্ষিপ্তসার রইল:

  • আমাদের যদি সম্ভব হয় তবে এটি করা উচিত। এই বিশেষ সমস্যার জন্য আপনি যে কোনও সমাধান চয়ন করুন না কেন এটি আপনাকে আরও ডিজাইনের নমনীয়তা এবং আপনার ডেটা নিয়ন্ত্রণ করে। সমস্ত অ্যাক্সেস তারপরে কেবলমাত্র ডাটাবেসের যুক্তির শর্ত না করে ব্যবসায়ের যুক্তির দিক দিয়ে "লেনদেনের" হয়ে যায়।
  • আপনি আপনার মডেল ঝরঝরে রাখতে পারেন
  • আপনি ব্যবসায়ের বিধিগুলির বিস্তৃত পরিসর এবং জটিলতা "প্রয়োগ" করতে পারেন (ডিআরআইয়ের তুলনায় "প্রয়োগ" ধারণাটি একটি লুজার হিসাবে লক্ষ্য করা যায়)
  • মডেলটিকে আরও শক্তিশালী অন্তর্নিহিত সততা দেওয়ার জন্য আপনি যেখানেই ব্যবহারিক ডিআরআই ব্যবহার করতে পারেন - এবং এটি আপনার লেনদেনের যুক্তিতে একটি চেক হিসাবে কাজ করতে পারে
  • আপনাকে যে ঝামেলা করছে এমন বেশিরভাগ পারফরম্যান্স সমস্যাগুলি গলে যাবে
  • নতুন প্রয়োজনীয়তার পরিচয় দেওয়া অনেক সহজ হতে পারে - উদাহরণস্বরূপ: বিতর্কিত লেনদেনের জটিল নিয়মগুলি আপনাকে খাঁটি ডিআরআই পদ্ধতির হাত থেকে দূরে সরিয়ে দিতে বাধ্য করতে পারে, যার অর্থ প্রচুর অপচয় করা প্রচেষ্টা
  • Historicalতিহাসিক তথ্য বিভাজন বা সংরক্ষণাগার অনেক কম ঝুঁকিপূর্ণ এবং বেদনাদায়ক হয়ে ওঠে

--edit

জটিলতা বা ঝুঁকি যোগ না করে সংরক্ষণাগারটি মঞ্জুরি দেওয়ার জন্য, আপনি অবিচ্ছিন্নভাবে উত্পন্ন উত্পন্ন সারসংক্ষেপ সারিগুলি পৃথক সারসংক্ষেপ টেবিলের মধ্যে রাখতে পছন্দ করতে পারেন (@ অ্যান্ড্রু এবং @ গারিকের কাছ থেকে ধার নেওয়া)

উদাহরণস্বরূপ, যদি সংক্ষিপ্তগুলি মাসিক হয়:

  • প্রতিবার কোনও লেনদেন হয় (আপনার এপিআই এর মাধ্যমে) সেখানে সামঞ্জস্য আপডেট হয় বা সংক্ষিপ্ত সারণিতে inোকানো হয়
  • সংক্ষিপ্তসার টেবিলটি কখনই সংরক্ষণাগারভুক্ত হয় না , তবে আর্কাইভের লেনদেনগুলি সরল আ মু মুছে যায় (বা ড্রপ পার্টিশন?)
  • সংক্ষিপ্ত সারণীর প্রতিটি সারিতে 'উদ্বোধনী ভারসাম্য' এবং 'পরিমাণ' অন্তর্ভুক্ত রয়েছে
  • 'খোলার ভারসাম্য' + 'পরিমাণ'> 0 এবং 'খোলার ভারসাম্য>> 0 এর মতো সীমাবদ্ধতাগুলি সারাংশ সারণীতে প্রয়োগ করা যেতে পারে
  • সাম্প্রতিক সারিগুলি সর্বশেষ সারসংক্ষেপ সারিটি লক করা সহজ করার জন্য একটি মাসিক ব্যাচে sertedোকানো যেতে পারে (সর্বদা চলতি মাসের জন্য একটি সারি থাকবে)

আপনার সম্পাদনা সম্পর্কে: সুতরাং আপনি কি এই ব্যালেন্সের টেবিলটি মূল ব্যালেন্সের টেবিলের পাশে রাখার প্রস্তাব করছেন? ব্যালেন্সের টেবিলটি কী কার্যকরভাবে একটি সারসংক্ষেপ সারণীতে পরিণত হয় যা কেবলমাত্র চলতি মাসের রেকর্ড রয়েছে (যেহেতু উভয়ই একই ধরণের ডেটা সংরক্ষণ করবে)? যদি আমি সঠিকভাবে বুঝতে পেরেছি, তবে কেন কেবল সংক্ষিপ্ত টেবিলের উপর উপযুক্ত পার্টিশন দিয়ে ব্যালেন্স টেবিলটি প্রতিস্থাপন করবেন না?
নিক চ্যামাস

দুঃখিত আপনি ঠিক তা অস্পষ্ট - আমার অর্থ ব্যালেন্স টেবিলটি ছড়িয়ে দেওয়া কারণ বর্তমান ভারসাম্যটি পাওয়ার জন্য সারসংক্ষেপ টেবিলটিতে এটি সর্বদা একটি মূল দৃষ্টিভঙ্গি হবে (অ্যান্ড্রুজের পরামর্শ এএফাইকের সাথে সত্য নয়)। সুবিধাটি হ'ল আগের সময়গুলিতে ব্যালেন্স গণনা করা সহজ হয়ে যায় এবং ভারসাম্যগুলি ভুল হয়ে গেলে ব্যালেন্সগুলির জন্য একটি পরিষ্কার নিরীক্ষার ট্রেইল রয়েছে।
জ্যাক ডগলাস

6

নিক।

মূল ধারণাটি একই টেবিলের মধ্যে ভারসাম্য এবং লেনদেনের রেকর্ড সংরক্ষণ করে। এটা historতিহাসিকভাবে আমি ভেবেছিলাম ঘটেছে। সুতরাং এক্ষেত্রে আমরা কেবল সর্বশেষ সংক্ষিপ্ত রেকর্ডটি সনাক্ত করে ভারসাম্য পেতে পারি।

 id   user_id    currency_id      amount    is_summary (or record_type)
----------------------------------------------------
  1       3              1       10.60             0
  2       3              1       10.60             1    -- summary after transaction 1
  3       3              1      -55.00             0
  4       3              1      -44.40             1    -- summary after transactions 1 and 3
  5       3              1      -12.12             0
  6       3              1      -56.52             1    -- summary after transactions 1, 3 and 5 

আরও ভাল রূপটি সংক্ষিপ্ত রেকর্ডের সংখ্যা হ্রাস পাচ্ছে। দিনের শেষে (এবং / অথবা শুরু) আমাদের একটি ভারসাম্য রেকর্ড থাকতে পারে। আপনি যেমন জানেন যে প্রতিটি ব্যাঙ্ককে operational dayএই দিনটির জন্য কিছু সংক্ষিপ্ত ক্রিয়াকলাপ খুলতে হবে এবং বন্ধ করতে হবে। এটি আমাদের প্রতিদিনের ভারসাম্য রেকর্ডটি ব্যবহার করে সুদের সহজ গণনা করতে দেয় , উদাহরণস্বরূপ:

user_id    currency_id      amount    is_summary    oper_date
--------------------------------------------------------------
      3              1       10.60             0    01/01/2011 
      3              1      -55.00             0    01/01/2011
      3              1      -44.40             1    01/01/2011 -- summary at the end of day (01/01/2011)
      3              1      -12.12             0    01/02/2011
      3              1      -56.52             1    01/02/2011 -- summary at the end of day (01/02/2011)

ভাগ্য।


4

আপনার প্রয়োজনীয়তার উপর ভিত্তি করে 1 বিকল্পটি সবচেয়ে ভাল প্রদর্শিত হবে। যদিও আমার ডিজাইনটি কেবলমাত্র লেনদেন সারণিতে সন্নিবেশগুলিকে অনুমতি দেওয়ার জন্য চাইবে। রিয়েল টাইম ব্যালেন্স টেবিল আপডেট করার জন্য এবং লেনদেনের টেবিলে ট্রিগার রাখুন। আপনি এই টেবিলগুলিতে অ্যাক্সেস নিয়ন্ত্রণ করতে ডাটাবেস অনুমতি ব্যবহার করতে পারেন।

এই পদ্ধতির মধ্যে, রিয়েল টাইম ব্যালেন্সটি লেনদেন সারণির সাথে সুসংগত হওয়ার নিশ্চয়তা দেওয়া হয়। সঞ্চিত পদ্ধতি বা পিএসকিএল বা জেডিবিসি ব্যবহার করা হয় কিনা তা বিবেচ্য নয়। প্রয়োজনে আপনার নেতিবাচক ভারসাম্য পরীক্ষা করতে পারেন। পারফরম্যান্স কোনও সমস্যা হবে না। রিয়েল টাইম ব্যালেন্সটি পেতে, এটি একটি সিঙ্গলটন ক্যোয়ারী।

সংরক্ষণাগার এই পদ্ধতির উপর প্রভাব ফেলবে না। প্রতিবেদনের মতো জিনিসের প্রয়োজন হলে আপনার কাছে একটি সাপ্তাহিক, মাসিক, বার্ষিক সংক্ষিপ্ত সারণী থাকতে পারে।


3

ওরাকলে আপনি কেবলমাত্র লেনদেনের টেবিলটি দিয়ে এটিতে দ্রুত রিফ্রেশযোগ্য ম্যাটরিয়ালাইজ ভিউ ব্যবহার করে এটি করতে পারেন যা ভারসাম্য গঠনে একত্রিত করে। আপনি মেটেরালাইজড ভিউতে ট্রিগারটি সংজ্ঞায়িত করেন। যদি ম্যাটেরিয়ালাইজড ভিউ'কে 'অন কমিট' দিয়ে সংজ্ঞায়িত করা হয়, তবে এটি কার্যকরভাবে বেস টেবিলগুলিতে ডেটা যুক্ত / পরিবর্তন করতে বাধা দেয়। ট্রিগার বৈধ ডেটা [ইন] সনাক্ত করে এবং একটি ব্যতিক্রম উত্থাপন করে, যেখানে এটি লেনদেনকে রোলব্যাক করে। একটি দুর্দান্ত উদাহরণ এখানে http://www.sqlsnippets.com/en/topic-12896.html

আমি স্ক্যালসার্ভার জানি না তবে সম্ভবত এটির অনুরূপ বিকল্প রয়েছে?


2
ওরাকলে ম্যাটারিয়ালাইজড ভিউগুলি এসকিউএল সার্ভার "ইনডেক্সড ভিউ" এর সমান, তবে তারা ওরাকলের 'অন কমিট' আচরণের মতো সুস্পষ্টভাবে পরিচালিত পদ্ধতির পরিবর্তে স্বয়ংক্রিয়ভাবে রিফ্রেশ করে। দেখুন social.msdn.microsoft.com/Forums/fi-FI/transactsql/thread/... এবং techembassy.blogspot.com/2007/01/...
GregW
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.