কেন স্বাক্ষরযুক্ত পূর্ণসংখ্যা পোস্টগ্র্রেএসকিউএল এ উপলব্ধ নয়?


113

আমি এই পোস্টটি জুড়ে এসেছি ( মাইএসকিউএলে টিনিন্যান্ট, স্মার্টিন্ট, মিডিয়ামিন্ট, বিগিন্ট এবং ইনট এর মধ্যে পার্থক্য কী? ) এবং বুঝতে পেরেছি যে পোস্টগ্র্যাসকিউএল স্বাক্ষরযুক্ত পূর্ণসংখ্যাকে সমর্থন করে না।

কেউ কেন এটি কেন তা ব্যাখ্যা করতে সহায়তা করতে পারে?

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

ধন্যবাদ।


এখনও না তবে শীঘ্রই এবং আমরা পোস্টগ্রাইএসকিউএল এ যাওয়ার কথা ভাবছি।
অ্যাড্রিয়ান হয়ে

4
আমি মনে করি না যে নির্দিষ্ট সিদ্ধান্ত কেন নেওয়া হয়েছে তা জিজ্ঞাসার জন্য এটিই সেরা জায়গা, পোস্টগ্রিসএসকিউএল মেলিং তালিকার মধ্যে একটি আরও উপযুক্ত হতে পারে। আপনি যদি স্ব- বর্ধমান মান চান তবে (1 থেকে 2147483647) serialবা bigserial(1 থেকে 9223372036854775807) ব্যবহার করুন। একটি স্বাক্ষরিত 64 বিট পূর্ণসংখ্যা সম্ভবত যথেষ্ট ঘরের চেয়ে বেশি প্রস্তাব দেয়।
মিউ খুব ছোট

4
ধন্যবাদ @ মিস্টুশোর্ট এটি প্রাথমিক কী ইস্যুটির উত্তর দিয়েছে। তবে স্বাক্ষরবিহীন পূর্ণসংখ্যার ধরণটি কীভাবে অটো বর্ধিত বা প্রাথমিক কী নয়? আমার কাছে কলাম রয়েছে যা স্বাক্ষরবিহীন পূর্ণসংখ্যা সঞ্চয় করে যা 0 থেকে 2 ^ 32 অবধি।
অ্যাড্রিয়ান হয়ে

4
পোস্টগ্র্রেএসকিউএল ডক্সের মাধ্যমে দ্রুত চালানো (পোস্টগ্রেএসকিউএল.আর / ডকস / কর্নার / ইন্টারেক্টিভ / ইন্ডেক্স এইচটিএমএল ) পোস্টগ্রিএসকিউএল কী সক্ষম তা সম্পর্কে আরও ভাল ধারণা পেতে আপনাকে সহায়তা করতে পারে। এই দিনগুলিতে আমি মাইএসকিউএল ব্যবহার করার একমাত্র কারণ হ'ল যদি ইতিমধ্যে আমি এতে প্রচুর পরিমাণে বিনিয়োগ করেছিলাম: পোস্টগ্রিসএসকিউএল দ্রুত, দরকারী বৈশিষ্ট্যযুক্ত এবং লোকেদের দ্বারা নির্মিত যা তাদের ডেটা সম্পর্কে বেশ অসতর্ক। আইএমও অবশ্যই :)
মিউ খুব কম

পয়েন্টারগুলির জন্য আবার @ মিমিস্টুশোর্টকে ধন্যবাদ।
অ্যাড্রিয়ান হয়ে

উত্তর:


47

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

http://www.postgresql.org/docs/9.4/static/sql-createdomain.html

 CREATE DOMAIN name [ AS ] data_type
    [ COLLATE collation ]
    [ DEFAULT expression ]
    [ constraint [ ... ] ]
 where constraint is:
 [ CONSTRAINT constraint_name ]
 { NOT NULL | NULL | CHECK (expression) }

ডোমেন একটি প্রকারের মতো তবে অতিরিক্ত বাধা সহ।

একটি দৃ concrete় উদাহরণের জন্য আপনি ব্যবহার করতে পারেন

CREATE DOMAIN uint2 AS int4
   CHECK(VALUE >= 0 AND VALUE < 65536);

আমি টাইপটি অপব্যবহার করার চেষ্টা করার সময় এখানে পিএসকিএল দেয়।

ডিএস 1 = # নির্বাচন (346346 :: uint2);

ত্রুটি: ডোমেন uint2 এর মান "uint2_check" সীমাবদ্ধতা লঙ্ঘন করে


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

এই পদ্ধতির সাথে একমাত্র সমস্যা হ'ল আপনি 15 টি বিট ডেটা স্টোরেজ "নষ্ট" করছেন যা অব্যবহৃত। চেকটি উল্লেখ না করাতে কিছুটা দক্ষতার পরিমাণও ব্যয় হয়। এর চেয়ে ভাল সমাধান হ'ল পোস্টগ্র্রেস প্রথম শ্রেণীর ধরণের হিসাবে স্বাক্ষরযুক্ত adding 20 মিলিয়ন রেকর্ড সহ একটি সারণীতে এবং এর মতো সূচিকৃত ক্ষেত্রের মধ্যে আপনি অব্যক্ত বিটগুলিতে 40MB স্থান নষ্ট করছেন। যদি আপনি অন্য 20 টি টেবিল জুড়ে অপব্যবহার করে থাকেন তবে আপনি এখন 800 এমবি স্থান নষ্ট করছেন।
tpartee

85

এটি এসকিউএল স্ট্যান্ডার্ডে নেই, সুতরাং এটি বাস্তবায়নের সাধারণ আবেদন কম।

অনেকগুলি পৃথক পূর্ণসংখ্যার ধরণটি টাইপ রেজোলিউশন সিস্টেমটিকে আরও ভঙ্গুর করে তোলে, তাই মিশ্রণে আরও বেশি প্রকার যুক্ত করার ক্ষেত্রে কিছুটা প্রতিরোধ ব্যবস্থা রয়েছে।

এটি বলেছিল, এটি কেন করা যায়নি তার কোনও কারণ নেই। এটি কেবল অনেক কাজ।


35
এই প্রশ্নটি যথেষ্ট জনপ্রিয় যে এটি ঠিক করার জন্য আমি বেরিয়ে এসেছি
পিটার

স্বাক্ষরবিহীন পূর্ণসংখ্যার লিটারালগুলির জন্য ইনপুট / আউটপুট রূপান্তরগুলি হওয়া খুব দরকারী। এমনকি কেবল একটি to_charপ্যাটার্নও।
বার্গি

37

আপনি একটি চেক সীমাবদ্ধতা ব্যবহার করতে পারেন, যেমন:

CREATE TABLE products (
    product_no integer,
    name text,
    price numeric CHECK (price > 0)
);

এছাড়াও পোস্টগ্র্রেএসকিউএল এর রয়েছে smallserial, serialএবং স্বতঃবৃদ্ধির bigserialজন্য প্রকারগুলি।


2
একটি জিনিস উল্লেখ করার জন্য, আপনার চেক ব্যবহার করে এমন কলামগুলিতে কোনও NULL থাকতে পারে না।
মিনিটিস

1
@ মিনুতিস আপনি কি নিশ্চিত যে আপনার কাছে x নীল বা x 4 ও 40 এর মধ্যে নেই
jgmjgm

এবং এটি আপনাকে ঠিক তেমন রেজোলিউশন দেয় না যেমনটি এটি স্বাক্ষরযুক্ত স্বাক্ষরিত হলে would অর্থ স্বাক্ষরবিহীন int পর্যন্ত যেতে পারে 2^32-1, ইতিমধ্যে স্বাক্ষরিত ইনটগুলি পর্যন্ত যেতে পারে 2^31-1
জুকসঅন আপনি

2
NULLএবং CHECKসম্পূর্ণ orthogonal হয়। আপনি থাকতে পারে NULL/ NOT NULLসহ বা ছাড়া কলাম CHECK। কেবলমাত্র নোট করুন, postgresql.org/docs/9.4/ddl-constraints.html এর নথি অনুসারে , CHECKNULL ফিরিয়ে নেওয়া সত্যের দিকে মূল্যায়ন করে, তাই আপনি যদি সত্যিই NULL রোধ করতে চান, তবে NOT NULLপরিবর্তে ব্যবহার করুন (বা এটি ছাড়াও CHECK)।
ফ্ল্যাভিওভস

CHECK ব্যবহার করে আমাকে আইপিভি 4 ঠিকানাগুলিতে সংরক্ষণ করতে দেয় না integer(এগুলি এলোমেলোভাবে ইতিবাচক বা নেতিবাচক না হয়ে যাওয়া ছাড়া, কমপক্ষে ..)
হানশেনরিক

5

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

এটি সম্পর্কে কারও কাছে জিজ্ঞাসা করা হলে টম লেন বলেছিলেন:

মূলত, এটির শূন্যতার সম্ভাবনা রয়েছে যদি না আপনি তাদের সংখ্যার প্রচারের স্তরক্রমের মধ্যে ফিট করার কোনও উপায় খুঁজে না পান যা প্রচুর বিদ্যমান অ্যাপ্লিকেশনগুলিকে ভঙ্গ করে না। আমরা এটিকে একাধিকবার দেখেছি, যদি মেমরিটি পরিবেশন করে, এবং এমন একটি কার্যক্ষম নকশা নিয়ে আসতে ব্যর্থ হয়েছে যা পোলা লঙ্ঘন বলে মনে হয় না।

"পোলা" কি? গুগল আমাকে 10 টি ফলাফল দিয়েছে যা অর্থহীন । নিশ্চিত নয় যে এটি রাজনৈতিকভাবে ভুল ধারণা এবং তাই সেন্সর করা হয়েছে। কেন এই অনুসন্ধান শব্দটি কোনও ফল দেয় না? যাই হোক.

আপনি খুব বেশি ঝামেলা ছাড়াই এক্সটেনশন প্রকার হিসাবে স্বাক্ষরযুক্ত ইনটগুলি প্রয়োগ করতে পারেন। আপনি যদি এটি সি-ফাংশন দিয়ে করেন তবে কোনও পারফরম্যান্স জরিমানা হবে না। আক্ষরিক ব্যবহারের জন্য আপনাকে পার্সার বাড়ানোর প্রয়োজন হবে না কারণ পিজিএসকিউএল এর স্ট্রিটগুলিকে আক্ষরিক হিসাবে ব্যাখ্যা করার মতো সহজ উপায় আছে, কেবল '4294966272' :: uint4 আপনার আক্ষরিক হিসাবে লিখুন। বর্ণগুলিও একটি বিশাল চুক্তি হওয়া উচিত নয়। আপনার এমনকি পরিসীমা ব্যতিক্রম করার দরকার নেই, আপনি কেবল '4294966273' :: uint4 :: int -1024 হিসাবে শব্দার্থক আচরণ করতে পারেন। অথবা আপনি একটি ত্রুটি নিক্ষেপ করতে পারেন।

আমি যদি এটি চাই, আমি এটা করতে হবে। তবে যেহেতু আমি এসকিউএল এর অন্য দিকে জাভা ব্যবহার করছি, আমার কাছে এটি খুব কম মূল্যহীন, যেহেতু জাভাতে সেই স্বাক্ষরযুক্ত স্বাক্ষরগুলি নেই gers সুতরাং আমি কিছুই লাভ। আমি যদি একটি বিগিন্ট কলাম থেকে একটি বিগইন্টেজার পাই তবে আমি এটির মধ্যে আগেই বিরক্ত হয়েছি যখন এটি দীর্ঘস্থায়ী হয়।

আরেকটি জিনিস, যদি আমার 32 বিট বা 64 বিট প্রকারের সংরক্ষণের প্রয়োজন হয় তবে আমি যথাক্রমে পোস্টগ্র্যাস এসকিউএল ইনট 4 বা ইনট 8 ব্যবহার করতে পারি, কেবল মনে আছে যে প্রাকৃতিক আদেশ বা পাটিগণিত নির্ভরযোগ্যভাবে কাজ করবে না। কিন্তু সংরক্ষণ এবং পুনরুদ্ধার এটি দ্বারা প্রভাবিত হয় না।


এখানে আমি কীভাবে একটি সাধারণ স্বাক্ষরবিহীন ইন্ট 8 প্রয়োগ করতে পারি:

প্রথম আমি ব্যবহার করব

CREATE TYPE name (
    INPUT = uint8_in,
    OUTPUT = uint8_out
    [, RECEIVE = uint8_receive ]
    [, SEND = uint8_send ]
    [, ANALYZE = uint8_analyze ]
    , INTERNALLENGTH = 8
    , PASSEDBYVALUE ]
    , ALIGNMENT = 8
    , STORAGE = plain
    , CATEGORY = N
    , PREFERRED = false
    , DEFAULT = null
)

সর্বনিম্ন 2 ফাংশন uint8_inএবং uint8_outআমি অবশ্যই প্রথমে সংজ্ঞায়িত করব।

CREATE FUNCTION uint8_in(cstring)
    RETURNS uint8
    AS 'uint8_funcs'
    LANGUAGE C IMMUTABLE STRICT;

CREATE FUNCTION uint64_out(complex)
    RETURNS cstring
    AS 'uint8_funcs'
    LANGUAGE C IMMUTABLE STRICT;

এটি সি uint8_funcs.c এ প্রয়োগ করতে হবে। তাই আমি এখান থেকে জটিল উদাহরণটি ব্যবহার করে এটিকে সহজ করে তুলি:

PG_FUNCTION_INFO_V1(complex_in);

Datum complex_in(PG_FUNCTION_ARGS) {
    char       *str = PG_GETARG_CSTRING(0);
    uint64_t   result;

    if(sscanf(str, "%llx" , &result) != 1)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                 errmsg("invalid input syntax for uint8: \"%s\"", str)));

    return (Datum)SET_8_BYTES(result);
}

আহ ভাল, বা আপনি এটি ইতিমধ্যে এটি সম্পন্ন দেখতে পারেন ।


1
আমি অনুমান করছি পোলা হ'ল "সর্বনিম্ন বিস্ময়ের মূলনীতি"। এটি প্রস্তাব দেয় যে পরিবর্তনের অপ্রত্যাশিত উপায়ে বিদ্যমান আচরণ পরিবর্তন করার সম্ভাবনা রয়েছে।
ডক্টর এভাল

1

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

https://www.postgresql.org/docs/10/datatype-numeric.html

integer     4 bytes     typical choice for integer  -2147483648 to +2147483647
serial  4 bytes     autoincrementing integer    1 to 2147483647

0

Postgres একটি স্বাক্ষরবিহীন পূর্ণসংখ্যা যে ধরনের অনেক অজান্তে হয় আছে: OID

oidটাইপ বর্তমানে একটি স্বাক্ষরবিহীন চার বাইট পূর্ণসংখ্যা হিসাবে বাস্তবায়িত হয়। [...]

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

এটি কোনও সংখ্যার মতো নয়, এবং এটির সাথে কোনও গাণিতিক (বা বিটওয়াইজ অপারেশন) করার চেষ্টা করা ব্যর্থ হতে চলেছে। এছাড়াও, এটি মাত্র 4 বাইট ( INTEGER), কোনও 8 বাইট ( BIGINT) স্বাক্ষরবিহীন টাইপ নেই।

সুতরাং এটি নিজেই ব্যবহার করা সত্যিই ভাল ধারণা নয় এবং আমি অন্যান্য সমস্ত উত্তরগুলির সাথে একমত যে পোস্টগ্রিস্কল ডাটাবেস ডিজাইনে আপনার সিরিয়াল প্রাথমিক কীটির জন্য সর্বদা একটি INTEGERবা BIGINTকলাম ব্যবহার করা উচিত - এটি নেতিবাচক ( ) থেকে শুরু করা বা এটির অনুমতি দেওয়া চারপাশে মোড়ানো ( ) আপনি যদি পুরো ডোমেনটি ক্লান্ত করতে চান।MINVALUECYCLE

তবে অন্য ডিবিএমএস থেকে আপনার স্থানান্তরের মতো এটি ইনপুট / আউটপুট রূপান্তরকরণের জন্য বেশ কার্যকর। 2147483648একটি পূর্ণসংখ্যা কলামে মান সন্নিবেশ করানো " অভিভাবক: পরিসীমা ছাড়িয়ে পূর্ণসংখ্যার " দিকে পরিচালিত করবে, যখন এক্সপ্রেশনটি ব্যবহার 2147483648::OIDকরে ঠিক কাজ করে।
একইভাবে, পাঠ্য হিসাবে কোনও পূর্ণসংখ্যা কলামটি নির্বাচন করার সময় mycolumn::TEXT, আপনি কোনও সময়ে নেতিবাচক মান পাবেন তবে আপনার সাথে mycolumn::OID::TEXTসর্বদা একটি প্রাকৃতিক সংখ্যা পাবেন।

Dbfiddle.uk এ একটি উদাহরণ দেখুন ।


আপনার যদি অপারেশনগুলির প্রয়োজন না হয় তবে ওআইডি ব্যবহারের একমাত্র মান হ'ল আপনার সাজানোর ক্রমটি কাজ করে। যদি এটি আপনার প্রয়োজন হয়, জরিমানা। তবে শীঘ্রই কেউ একটি uint8 চাইবে এবং তারপরে সেগুলিও হারিয়ে যায়। নীচের লাইনটি হ'ল 32 বিট বা 64 বিট মান সংরক্ষণ করতে আপনি যথাক্রমে ইনট 4 এবং ইনট 8 ব্যবহার করতে পারেন, ক্রিয়াকলাপগুলির সাথে সাবধান হওয়া দরকার। তবে এটি একটি এক্সটেনশন লিখতে সহজ।
গুন্থার স্ক্যাডো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.