আইপি অ্যাড্রেসগুলি সংরক্ষণ করা হচ্ছে - বর্ণচর্চা (45) বনাম ভার্বিনারি (16)


11

আমি দুটি ক্ষেত্রের সাথে একটি টেবিল তৈরি করতে যাচ্ছি - IDহিসাবে BIGINTএবং IPAddressহয় varchar(45)বা হিসাবে varbinary(16)। ধারণাটি হ'ল সমস্ত অনন্য আইপি ঠিকানা সঞ্চয় করা এবং অন্য টেবিলগুলিতে IDপ্রকৃত পরিবর্তে একটি রেফারেন্স ব্যবহার করা IP address

সাধারণত, আমি একটি সঞ্চিত প্রক্রিয়া তৈরি করতে যাচ্ছি যা IDপ্রদত্ত জন্য প্রদত্ত ফিরিয়ে দিচ্ছে IP addressবা (যদি ঠিকানাটি খুঁজে পাওয়া না যায়) ঠিকানা সন্নিবেশ করান এবং জেনারেটটি ফিরিয়ে দিন ID

আমি অনেক রেকর্ড রাখার প্রত্যাশা করছি (আমি ঠিক কতটি বলতে পারি না) তবে আমার উপরের সঞ্চিত প্রক্রিয়াটি যত তাড়াতাড়ি সম্ভব সম্পাদন করা দরকার। সুতরাং, আমি ভাবছি কীভাবে আসল আইপি ঠিকানাটি সংরক্ষণ করতে হবে - পাঠ্য বা বাইট ফর্ম্যাটে। যা ভাল হতে চলেছে?

আমি SQL CLRআইপি ঠিকানা বাইটগুলি স্ট্রিং এবং বিপরীতে রূপান্তর করার জন্য ইতিমধ্যে লিখিত ফাংশন লিখেছি , সুতরাং রূপান্তর কোনও সমস্যা নয় (উভয় IPv4এবং উভয়ের সাথে কাজ করে IPv6)।

আমি অনুমান করি যে অনুসন্ধানটি অপ্টিমাইজ করার জন্য আমার একটি সূচক তৈরি করা দরকার, তবে আমি নিশ্চিত নই যে আমার IP addressক্ষেত্রটি ক্লাস্টারড ইনডেক্সে অন্তর্ভুক্ত করা উচিত , বা আলাদা সূচি তৈরি করা উচিত এবং কোন ধরণের সাহায্যে অনুসন্ধানটি আরও দ্রুত হবে?


2
কমপক্ষে আইপিভি 4 এর জন্য, কেন 4 টি ক্ষুদ্র চিহ্ন? তারপরে তারা প্রকৃতপক্ষে মানব পাঠযোগ্য এবং আপনাকে কোনও রূপান্তর করতে হবে না। নির্দিষ্ট ধরণের অনুসন্ধানগুলি (সঠিক মিল, সাবনেট, ইত্যাদি) উপস্থাপনের জন্য আপনি সমস্ত ধরণের স্থায়ী গণিত কলামগুলিও তৈরি করতে পারেন।
অ্যারন বারট্রান্ড

যদি IPv4কেসটি কেবল আমার অনুমানের জন্যই হত তবে আমি ঠিকানাটিকে রূপান্তর করব INTএবং ক্ষেত্রটিকে সূচক কী হিসাবে ব্যবহার করব। তবে এর জন্য IPv6আমার দুটি BIGINTক্ষেত্র ব্যবহার করা দরকার এবং আমি মানটি একটি ক্ষেত্রে সংরক্ষণ করতে পছন্দ করি - আমার কাছে এটি আরও প্রাকৃতিক বলে মনে হয়।
পেয়েছি

1
এখনও বুঝতে পারছেন না কেন 4 টিআইআইএনআইএনটির পরিবর্তে আইএনটি? একই সঞ্চয়স্থান, সহজ ডিবাগিং, কম বোকা, আইএমএইচও। বিভিন্ন বৈধতা এবং অর্থ সহ যদি আপনার দুটি সম্পূর্ণ ভিন্ন ধরণের হয় তবে কেন তাদের একই কলামটি ব্যবহার করা দরকার? যদি আপনি বাজি ধরেন যে একটি একক কলামটি সহজ, তবে কেন কেবল এসকিউএল_ভিআরআইএনটি ব্যবহার করবেন না, তবে আপনাকে কোনও কিছুর জন্য চিন্তা করতে হবে না। আপনি তারিখ এবং স্ট্রিং এবং সংখ্যা সঞ্চয় করতে পারেন এবং প্রত্যেকে একটি বিশাল, অকেজো কলামে একটি বড় পার্টি করতে পারেন ...
অ্যারন বারট্র্যান্ড

আইপি ঠিকানাগুলি কোথা থেকে আসছে? তারা কি কখনও মাস্ক / সাবনেট অন্তর্ভুক্ত করবে (যেমন 10.10.10.1/124)? আমি এটি ওয়েব সার্ভার লগগুলি থেকে দেখতে পেয়েছি এবং সহজেই বিগিন্টে অনুবাদ করি না (আইএনটি কাজ করবে না কারণ গণনাটি একটি স্বাক্ষরিত আইএনটি প্রয়োজন, অবশ্যই না হলে আপনি 0টিকে ধরে নিতে স্বাভাবিকীকরণটি সত্যই অন্তর্ভুক্ত করেছেন -2.14xxxx বিলিয়ন)। আমার ধারণা, সাবনেট মাস্কটি কেবলমাত্র একটি অতিরিক্ত TINYINT ক্ষেত্র হতে পারে। তবে আমি বুঝতে পারি যে বিজিআইএনটি হিসাবে সংরক্ষণ করতে ইচ্ছুক যদি এটি মানচিত্রের জন্য অক্ষাংশ / দ্রাঘিমাংশের একটি ডিবি পর্যন্ত মেলে। হারুন যেমন উল্লেখ করেছেন, এটি একটি স্থির গণিত কর্নেল হতে পারে।
সলোমন রুটজকি

উত্তর:


13

কীভাবে আসল আইপি ঠিকানা সঞ্চয় করা যায় - পাঠ্য বা বাইট ফর্ম্যাটে। যা ভাল হতে চলেছে?

যেহেতু এখানে "পাঠ্য" বোঝায় VARCHAR(45)এবং "বাইটস" বোঝায় VARBINARY(16), আমি বলব: না

নিম্নলিখিত তথ্য ( আইপিভি 6 উইকিপিডিয়া নিবন্ধ থেকে ) দেওয়া:

ঠিকানার প্রতিনিধিত্ব
একটি আইপিভি 6 ঠিকানার 128 বিটগুলি 16 টি বিটের 8 টি গ্রুপে প্রতিনিধিত্ব করা হয়েছে। প্রতিটি গ্রুপ 4 টি হেক্সাডেসিমাল অঙ্ক হিসাবে লেখা হয় এবং গ্রুপগুলি কলোন দ্বারা বিভক্ত হয় (:)। ঠিকানা 2001: 0db8: 0000: 0000: 0000: ff00: 0042: 8329 এই উপস্থাপনের একটি উদাহরণ।

সুবিধার জন্য, একটি আইপিভি 6 ঠিকানা সংক্ষিপ্ত স্বরলিখিত সংক্ষেপে নিম্নলিখিত নিয়ম প্রয়োগ করে সম্ভব হবে, যেখানে সম্ভব।

  • হেক্সাডেসিমাল সংখ্যাগুলির যে কোনও গ্রুপের এক বা একাধিক নেতৃস্থানীয় শূন্যগুলি সরানো হয়েছে; এটি সাধারণত সমস্ত বা নেতৃস্থানীয় শূন্যগুলির কোনওটির সাথেই করা হয়। উদাহরণস্বরূপ, 0042 গ্রুপটি 42 এ রূপান্তরিত হয়েছে।
  • জিরোগুলির একটানা বিভাগগুলি একটি ডাবল কোলন (: :) দ্বারা প্রতিস্থাপন করা হয়েছে। ডাবল কোলন কেবলমাত্র একবার ঠিকানাতে ব্যবহার করা যেতে পারে, কারণ একাধিক ব্যবহারের ফলে ঠিকানাটি অনির্ধারিত হয়। আরএফসি 5952 পরামর্শ দেয় যে ডাবল কোলন অবশ্যই শূন্যের বাদ পড়া একক বিভাগ বোঝাতে ব্যবহার করা উচিত নয় [[৪১]

এই বিধি প্রয়োগের একটি উদাহরণ:

        প্রাথমিক ঠিকানা: 2001: 0db8: 0000: 0000: 0000: ff00: 0042: 8329
        প্রতিটি গ্রুপে সমস্ত নেতৃস্থানীয় জিরো অপসারণের পরে: 2001: db8: 0: 0: ff00: 42: 8329 শূন্যের
        পরপর বিভাগগুলি বাদ দেওয়ার পরে: 2001 : db8 :: ff00: 42: 8329

আমি VARBINARY(2)8 টি গ্রুপকে উপস্থাপন করতে 8 টি ক্ষেত্র ব্যবহার করে শুরু করব । গ্রুপ 5 - 8 এর ক্ষেত্রগুলি হ'ল NULLসেগুলি কেবল আইপিভি 6 ঠিকানার জন্য ব্যবহৃত হবে। গ্রুপ 1 - 4 এর ক্ষেত্রগুলি NOT NULLহ'ল আইপিভি 4 এবং আইপিভি 6 ঠিকানা উভয়ের জন্যই ব্যবহৃত হবে।

প্রতিটি গ্রুপকে স্বাধীন রেখে (তাদের এক VARCHAR(45)বা এক VARBINARY(16)বা দুটি BIGINTক্ষেত্রেই একত্রিত করার বিপরীতে ) আপনি দুটি প্রধান সুবিধা পাবেন:

  1. কোনও নির্দিষ্ট উপস্থাপনার জন্য ঠিকানাটি পুনর্গঠন করা অনেক সহজ। অন্যথায়, (: :) এর সাথে একটানা গ্রুপের শূন্যগুলি প্রতিস্থাপন করতে আপনাকে এটিকে পার্স করতে হবে। তাদের পৃথক রাখা সহজ IF/ IIF/ CASEবিবৃতি এটিকে সহজতর করার অনুমতি দেয় ।
  2. হয় আপনি সক্ষম করে IPv6 অ্যাড্রেসের স্থান একটি টন সংরক্ষণ করতে হবে ROW COMPRESSIONবা PAGE COMPRESSION। যেহেতু উভয় প্রকারের কমপ্রেসনই 0x000 টি বাইট গ্রহণের ক্ষেত্রগুলিকে অনুমতি দেবে , তাই এই গ্রুপগুলির শূন্যগুলি এখন আপনার জন্য কোনও ব্যয় করবে না। অন্যদিকে, যদি আপনি উপরের উদাহরণটি (উইকিপিডিয়া উদ্ধৃতিতে) সংরক্ষণ করেন, তবে মাঝখানে সমস্ত শূন্যের 3 টি সেট তাদের পুরো পরিমাণের স্থান গ্রহণ করবে (যদি না আপনি না করে থাকেন VARCHAR(45)এবং স্বল্প চিহ্নের সাথে না যান) , তবে এটি সূচীকরণের জন্য ভাল কাজ করতে পারে না এবং পুরো ফর্ম্যাটে এটি পুনর্গঠন করার জন্য বিশেষ পার্সিংয়ের প্রয়োজন হবে, সুতরাং ধরে নেওয়া যাক এটি কোনও বিকল্প নয় ;-)।

যদি আপনাকে নেটওয়ার্ক ক্যাপচার করতে হয় তবে তার জন্য একটি TINYINTক্ষেত্র তৈরি করুন , আহ, [Network]:-)

নেটওয়ার্ক মান সম্পর্কে আরও তথ্যের জন্য, এখানে আইপিভি 6 ঠিকানার অন্য উইকিপিডিয়া নিবন্ধ থেকে কিছু তথ্য :

নেটওয়ার্ক

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

নেটওয়ার্ক অ্যাড্রেস রেঞ্জগুলি সিআইডিআর স্বরলিপিতে লেখা হয়। ব্লকের প্রথম ঠিকানা (সমস্ত শূন্যের সমাপ্তি), একটি স্ল্যাশ (/) এবং উপসর্গের বিটগুলির আকারের সমান দশমিক মান দ্বারা একটি নেটওয়ার্ককে বোঝানো হয়। উদাহরণস্বরূপ, 2001 হিসাবে লিখিত নেটওয়ার্ক: db8: 1234 :: / 48 ঠিকানা 2001 এ শুরু হয়: db8: 1234: 0000: 0000: 0000: 0000: 0000 এবং 2001 এ শেষ হয়: db8: 1234: ffff: ffff: ffff : ffff।

একটি ইন্টারফেস ঠিকানার রুটিং উপসর্গটি সরাসরি সিআইডিআর স্বরলিপি দ্বারা ঠিকানার সাথে নির্দেশিত হতে পারে। উদাহরণস্বরূপ, ঠিকানাটি 2001: db8: a :: 123 সাবনেট 2001: db8: a :: / 64 এর সাথে সংযুক্ত 2001: db8: a :: 123/64 হিসাবে একটি ইন্টারফেসের কনফিগারেশন।


ইনডেক্সিংয়ের জন্য, আমি বলতে চাই যে 8 টি গ্রুপ ক্ষেত্রে একটি নন-ক্লাস্টারড সূচক তৈরি করুন এবং সম্ভবত আপনি যদি এটি অন্তর্ভুক্ত করার সিদ্ধান্ত নেন তবে নেটওয়ার্ক ক্ষেত্র।


শেষ ফলাফল নিম্নলিখিত মত কিছু হতে হবে:

CREATE TABLE [IPAddress]
(
  IPAddressID INT          NOT NULL IDENTITY(-2147483648, 1),
  Group8      VARBINARY(2) NULL, -- IPv6 only, NULL for IPv4
  Group7      VARBINARY(2) NULL, -- IPv6 only, NULL for IPv4
  Group6      VARBINARY(2) NULL, -- IPv6 only, NULL for IPv4
  Group5      VARBINARY(2) NULL, -- IPv6 only, NULL for IPv4
  Group4      VARBINARY(2) NOT NULL, -- both
  Group3      VARBINARY(2) NOT NULL, -- both
  Group2      VARBINARY(2) NOT NULL, -- both
  Group1      VARBINARY(2) NOT NULL, -- both
  Network     TINYINT      NULL
);

ALTER TABLE [IPAddress]
  ADD CONSTRAINT [PK_IPAddress]
  PRIMARY KEY CLUSTERED
  (IPAddressID ASC)
  WITH (FILLFACTOR = 100, DATA_COMPRESSION = PAGE);

CREATE NONCLUSTERED INDEX [IX_IPAddress_Groups]
  ON [IPAddress] (Group1 ASC, Group2 ASC, Group3 ASC, Group4 ASC,
         Group5 ASC, Group6 ASC, Group7 ASC, Group8 ASC, Network ASC)
  WITH (FILLFACTOR = 100, DATA_COMPRESSION = PAGE);

মন্তব্য:

  • আমি স্বীকার করেছি যে আপনি BIGINTআইডি ক্ষেত্রটি ব্যবহার করার পরিকল্পনা করছেন তবে আপনি কি সত্যিই 4,294,967,295 টিরও বেশি অনন্য মান ক্যাপচার করবেন বলে আশা করছেন? যদি তা হয় তবে কেবল ক্ষেত্রটি বিগিন্ট হিসাবে পরিবর্তন করুন এবং আপনি তারপরে বীজের মানও 0 হতে পারবেন But তবে অন্যথায় আপনি INT ব্যবহার করা এবং সর্বনিম্ন মান দিয়ে শুরু করার চেয়ে ভাল are ।
  • যদি ইচ্ছা হয়, আপনি এই টেবিলটিতে এক বা একাধিক ননপারস্পিষ্ট গণিত কলাম যুক্ত করতে পারেন আইপিএড্রেসের পাঠ্য উপস্থাপনা ফেরত দিতে।
  • গ্রুপ * ক্ষেত্র ব্যবস্থা উদ্দেশ্যপূর্ণ যাচ্ছি নিচে , 8 থেকে 1 যাও, টেবিলে যাতে করছেন SELECT *প্রত্যাশিত অনুক্রমে ক্ষেত্র ফিরে আসবে। তবে সূচকগুলি তাদের 1 থেকে 8 পর্যন্ত চলেছে , এভাবেই তারা পূরণ করা হয়।
  • পাঠ্য আকারে মানগুলি উপস্থাপনের জন্য একটি গণিত কলামের একটি উদাহরণ (অসমাপ্ত) হ'ল:

    ALTER TABLE [IPAddress]
      ADD TextAddress AS (
    IIF([Group8] IS NULL,
        -- IPv4
        CONCAT(CONVERT(TINYINT, [Group4]), '.', CONVERT(TINYINT, [Group3]), '.',
          CONVERT(TINYINT, [Group2]), '.', CONVERT(TINYINT, [Group1]),
          IIF([Network] IS NOT NULL, CONCAT('/', [Network]), '')),
        -- IPv6
        LOWER(CONCAT(
          CONVERT(VARCHAR(4), [Group8], 2), ':', CONVERT(VARCHAR(4), [Group7], 2), ':',
          CONVERT(VARCHAR(4), [Group6], 2), ':', CONVERT(VARCHAR(4), [Group5], 2), ':',
          CONVERT(VARCHAR(4), [Group4], 2), ':', CONVERT(VARCHAR(4), [Group3], 2), ':',
          CONVERT(VARCHAR(4), [Group2], 2), ':', CONVERT(VARCHAR(4), [Group1], 2),
          IIF([Network] IS NOT NULL, CONCAT('/', [Network]), '')
         ))
       ) -- end of IIF
    );
    

    টেস্ট:

    INSERT INTO IPAddress VALUES (127, 0, 0, 0, 4, 22, 222, 63, NULL); -- IPv6
    INSERT INTO IPAddress VALUES (27, 10, 1234, 0, 45673, 200, 1, 6363, 48); -- IPv6
    INSERT INTO IPAddress VALUES (NULL, NULL, NULL, NULL, 192, 168, 2, 63, NULL); -- v4
    INSERT INTO IPAddress VALUES (NULL, NULL, NULL, NULL, 192, 168, 137, 29, 16); -- v4
    
    SELECT [IPAddressID], [Group8], [Group1], [Network], [TextAddress]
    FROM IPAddress ORDER BY [IPAddressID];
    

    ফলাফল:

    IPAddressID   Group8   Group1   Network  TextAddress
    -----------   ------   ------   -------  ---------------------
    -2147483646   0x007F   0x003F   NULL     007f:0000:0000:0000:0004:0016:00de:003f
    -2147483645   0x001B   0x18DB   48       001b:000a:04d2:0000:b269:00c8:0001:18db/48
    -2147483644   NULL     0x003F   NULL     192.168.2.63
    -2147483643   NULL     0x001D   16       192.168.137.29/16
    

SQL সার্ভার 2005, যেমন কলাম সংজ্ঞা হবে VARDECIMALউপর VARBINARYথেকে DATA_COMPRESSIONপাওয়া যাচ্ছে না?
ম্যাট

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

@ জেভিজি আপনি স্বাগত :) শুরু এবং শেষ আইপি ঠিকানাগুলি কীভাবে সংরক্ষণ করা হচ্ছে? আপনি কি আইপিভি 4 বা ভি 6 ঠিকানা ব্যবহার করছেন?
সলোমন রুটজকি

পুনঃটুইট আইপিভি 4 কোনও সমস্যা নয় কারণ আমি এটি পূর্ণসংখ্যা হিসাবে সঞ্চয় করতে পারি। দুর্ভাগ্যক্রমে, এসকিউএল সার্ভারটিতে এটি পরিচালনা করার জন্য 128 বিট পূর্ণসংখ্যা বা সংখ্যা সম্পর্কিত ডেটা টাইপ নেই। সুতরাং, আইপিভি 6 এর জন্য আমি এটি ভারবিনারি (16) এ সঞ্চয় করছি এবং তারপরে আমি বিস্তীর্ণ অপারেটরটি ব্যাপ্তিগুলির মধ্যে অনুসন্ধান করতে ব্যবহার করব। তবে, আমি আইপি রেঞ্জগুলিতে একাধিক ফলাফল পাচ্ছি, যা আমি সঠিক বলে মনে করি না। আমি যদি সম্ভব হয় তবে আইভিভি 4 এবং আইপিভি 6 উভয়ের জন্য একই ডেটা টাইপ ব্যবহার করতে চাই।
জে ওয়েজি

@ জেভিজি আমি প্রস্তাব দিতে যাচ্ছি BINARY(16);-)। আপনি কি দয়া করে আমাকে একটি প্রারম্ভ / সমাপ্তি সীমা এবং কমপক্ষে দুটি সারি দিয়ে ফিরে পেয়েছেন যা একটি বৈধ এবং কমপক্ষে একটি অবৈধ? এটি হতে পারে যে ভারবাইনারি কিছু মান সংক্ষিপ্ত করে।
সলোমন রুটজকি

1

ছোট সবসময় দ্রুত হতে চলেছে। ছোট মানগুলির সাহায্যে আপনি সেগুলির বেশিরভাগই একটি পৃষ্ঠায় ফিট করতে পারেন, সুতরাং কম আইও, সম্ভাব্য অগভীর বি-ট্রি ইত্যাদি

অন্যান্য সমস্ত জিনিস (অনুবাদ ওভারহেড, পঠনযোগ্যতা, সামঞ্জস্যতা, সিপিইউ লোড, সূচকের সরগবিতা ইত্যাদি) অবশ্যই সমান।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.