এসকিউএল সহ একটি পোস্টগ্রিস ডিবি 8.1-এ সমস্ত ক্রম তালিকাভুক্ত করুন


147

আমি পোস্টগ্রিজ থেকে মাইএসকিএলে একটি ডিবি রূপান্তর করছি।

যেহেতু আমি এমন কোনও সরঞ্জাম খুঁজে পাচ্ছি না যা নিজেই কৌতুকটি করে, তাই আমি সমস্ত পোস্টগ্রাসের ক্রমগুলি স্বতঃআগ্রহ মূল্যের সাথে মাইএসকিএলে স্বতঃসংশোধন আইডিতে রূপান্তর করতে যাচ্ছি।

সুতরাং, আমি কীভাবে একটি পোস্টগ্রিস ডিবিতে ( 8.1 সংস্করণ) সমস্ত সিকোয়েন্সটি সারণিতে এটি ব্যবহার করতে সক্ষম টেবিল, এসকিউএল কোয়েরির সাথে পরবর্তী মান ইত্যাদি দিয়ে তালিকাবদ্ধ করতে পারি?

information_schema.sequences8.4 রিলিজে আমি ভিউটি ব্যবহার করতে পারি না সে সম্পর্কে সচেতন থাকুন ।


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

@ জন আমি বলব যে পোস্টগ্রাগের সাথে লেগে থাকার আরও এক বিলিয়ন এবং অন্য একটি কারণ রয়েছে এবং আরও একশো বিলিয়ন কখনও মাইএসকিএল স্পর্শ করতে পারে না, তবে হ্যাঁ - আপনার
বক্তব্যটি

@ জন সেই সময়ে (২০০৯) আমাদের ডিল করার জন্য একটি সহজ ডাটাবেস দরকার - এবং
মাইএসকিএল

উত্তর:


250

নিম্নলিখিত কোয়েরিটি সমস্ত ক্রমের নাম দেয়।

SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';

সাধারণত একটি ক্রম হিসাবে নামকরণ করা হয় ${table}_id_seq। সাধারণ রেজেক্স প্যাটার্নের মিলটি আপনাকে সারণির নাম দেবে।

একটি ক্রমের শেষ মান পেতে নিম্নলিখিত কোয়েরিটি ব্যবহার করুন:

SELECT last_value FROM test_id_seq;

5
${table}_id_seqইঙ্গিতটি দরকারী ছিল
পিয়ের দ্য LESPINAY

${table}_${column}_seqস্ব-নির্মিত সিকোয়েন্সগুলির জন্য
এভজেনি নজড্রেভ

80

দ্রষ্টব্য, পোস্টগ্রিএসকিউএল ৮.৪ থেকে শুরু করে আপনি ডাটাবেজে ব্যবহৃত ক্রমগুলি সম্পর্কে সমস্ত তথ্য এর মাধ্যমে পেতে পারেন:

SELECT * FROM information_schema.sequences;

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


1
প্রতিলিপি: "সক্রিয়" দ্বারা উত্তরগুলি সাজান। প্রশ্ন ক্রমবর্ধমান হওয়ার সাথে সাথে উত্তরোত্তর আরও প্রাসঙ্গিক হয়ে উঠছে ..
রাভেরেন

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

নিশ্চিত করুন যে এই টেবিলটি পিজি 8.4 তে প্রবর্তিত হয়েছিল, আমি বরং সরকারী ডকুমেন্টেশনের পরে পিজি 8.2 বলব: postgresql.org/docs/8.2/infoschema-sequens.html
গিলাইলে হুস্তা

সেই "সমস্ত তথ্য" তে বর্তমান মান অন্তর্ভুক্ত নয়।
বার্ট

62

চালান:, psql -Eএবং তারপর\ds


1
আমার কেবল সিক্যুয়েন্সের তালিকার দরকার নেই, আমার যে টেবিলটি এটি ব্যবহার করা হয়েছে তার দরকার, পরবর্তী মান ইত্যাদি And এবং এসকিউএল
আমাকে

তারপরে, প্রতিটি অনুক্রমের উপর \ d <নাম> (এখনও পিএসকিএল-ই থাকা হচ্ছে)

আবার, এটি এসকিউএল-তে নেই এবং কোন সারণিতে ক্রমটি সংযুক্ত রয়েছে তা দেখায় না
এপেলিসিয়ারি

@ ওভাস্ট্রেগ: আমি আপনাকে যেভাবে বলেছিলাম তা কি আপনি চালিয়েছেন? এবং কেন না?

10
@avastreg: এটা করতে একবার । এবং এটি আপনাকে জিজ্ঞাসাগুলি দেখাবে!

26

একটু ব্যথার পরে, আমি এটি পেয়েছি।

এটি অর্জনের সর্বোত্তম উপায় হ'ল সমস্ত সারণী তালিকাভুক্ত করা

select * from pg_tables where schemaname = '<schema_name>'

এবং তারপরে, প্রতিটি টেবিলের জন্য, সমস্ত কলামগুলিকে গুণাবলী সহ তালিকাভুক্ত করুন

select * from information_schema.columns where table_name = '<table_name>'

তারপরে, প্রতিটি কলামের জন্য, এর ক্রম আছে কিনা তা পরীক্ষা করুন

select pg_get_serial_sequence('<table_name>', '<column_name>')

এবং তারপরে, এই ক্রম সম্পর্কে তথ্য পান

select * from <sequence_name>

13

ক্রম তথ্য: সর্বাধিক মান

SELECT * FROM information_schema.sequences;

ক্রম তথ্য: শেষ মান

SELECT * FROM <sequence_name>


11

স্বয়ংক্রিয়ভাবে উত্পন্ন সিকোয়েন্সগুলির মধ্যে সম্পর্ক (যেমন সিরিয়াল কলামগুলির জন্য তৈরি করা হয়েছে) এবং পিতামাতার সারণীটি সিকোয়েন্সের মালিকের বৈশিষ্ট্য দ্বারা মডেল করা হয়।

আপনি এই সম্পর্কটি ALTER SEQUENCE কম্যান্ডের মালিকানাধীন ক্লজ ব্যবহার করে সংশোধন করতে পারেন

উদাহরণস্বরূপ, foo_schema.foo_table দ্বারা স্বতঃসিদ্ধ foo_id ALTER SEQUENCE

এটি foo_table টেবিলের সাথে লিঙ্ক করতে সেট করতে

বা অলটার সিকোয়েন্সটি foo_id দ্বারা অনুমোদিত নয়

ক্রম এবং যে কোনও টেবিলের মধ্যে সংযোগ ভাঙতে

এই সম্পর্ক সম্পর্কিত তথ্য pg_d নির্ভর ক্যাটালগ সারণীতে সংরক্ষণ করা হয় ।

যোগদানের সম্পর্কটি হ'ল pg_d depend.objid -> pg_class.oid WHLE relind = 'S' - এর মধ্যে যোগসূত্র যা যোগ রেকর্ডের ক্রমকে যুক্ত করে এবং তারপরে pg_d depend.refobjid -> pg_class.oid WHERE relind = 'r', যা লিঙ্কটি যুক্ত করে নিজস্ব সম্পর্কের রেকর্ডে যোগ দিন (টেবিল)

এই কোয়েরিটি একটি ডাটাবেসে সমস্ত ক্রম -> টেবিল নির্ভরতা প্রদান করে। যেখানে ক্লজ এটিকে কেবল স্বয়ংক্রিয় উত্পাদিত সম্পর্কগুলি অন্তর্ভুক্ত করতে ফিল্টার করে, যা এটি কেবল সিরিয়াল টাইপযুক্ত কলামগুলির দ্বারা নির্মিত ক্রমিক প্রদর্শনগুলিতে সীমাবদ্ধ করে।

WITH fq_objects AS (SELECT c.oid,n.nspname || '.' ||c.relname AS fqname , 
                           c.relkind, c.relname AS relation 
                    FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace ),

     sequences AS (SELECT oid,fqname FROM fq_objects WHERE relkind = 'S'),  
     tables    AS (SELECT oid, fqname FROM fq_objects WHERE relkind = 'r' )  
SELECT
       s.fqname AS sequence, 
       '->' as depends, 
       t.fqname AS table 
FROM 
     pg_depend d JOIN sequences s ON s.oid = d.objid  
                 JOIN tables t ON t.oid = d.refobjid  
WHERE 
     d.deptype = 'a' ;

সারণী এবং ক্রমগুলির মধ্যে নির্ভরতার কার্যকর ব্যাখ্যা explanation কিন্তু আপনার জিজ্ঞাসাটি আমার জন্য সমস্ত সিকোয়েন্স খুঁজে পায় নি । দেখে মনে হচ্ছে যে কোনও ক্রম কোনও নির্ভরতা ছাড়াই বিদ্যমান।
ইভজেনি নজড্রেভ

হ্যাঁ, এই কোয়েরিটি স্পষ্টভাবে কেবল ক্রমগুলি প্রদর্শন করছে যা ডাটাবেস সিরিয়াল কলাম সংজ্ঞা দ্বারা সংজ্ঞায়িত হয়। উত্তরে এটি ব্যাখ্যা করা হয়েছে।
সেমি

5

আমি জানি এই পোস্টটি বেশ পুরানো, তবে আমি সিএমএসের সমাধানটি খুব দরকারী বলে খুঁজে পেলাম কারণ আমি টেবিল এবং কলামের সাথে একটি সিকোয়েন্স লিঙ্ক করার জন্য একটি স্বয়ংক্রিয় পদ্ধতি খুঁজছিলাম এবং ভাগ করতে চেয়েছিলাম। Pg_d depend કેટটাল টেবিল ব্যবহারের মূল ছিল। যা করা হয়েছিল তা আমি প্রসারিত করেছি:

WITH fq_objects AS (SELECT c.oid,n.nspname || '.' ||c.relname AS fqname ,
                           c.relkind, c.relname AS relation
                    FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace ),

     sequences AS (SELECT oid,fqname FROM fq_objects WHERE relkind = 'S'),
     tables    AS (SELECT oid, fqname FROM fq_objects WHERE relkind = 'r' )
SELECT
       s.fqname AS sequence,
       '->' as depends,
       t.fqname AS table,
       a.attname AS column
FROM
     pg_depend d JOIN sequences s ON s.oid = d.objid
                 JOIN tables t ON t.oid = d.refobjid
                 JOIN pg_attribute a ON a.attrelid = d.refobjid and a.attnum = d.refobjsubid
WHERE
     d.deptype = 'a' ;

এই সংস্করণটি ফিরে আসা ক্ষেত্রের তালিকায় কলাম যুক্ত করে। টেবিলের নাম এবং কলামের নাম দুটোই হাতে রেখে, পিজি_সেট_সিরিয়াল_সিকোয়েন্সে কল করার ফলে এটি নিশ্চিত করা সহজ হয় যে ডাটাবেসে সমস্ত ক্রম সঠিকভাবে সেট করা আছে। উদাহরণ স্বরূপ:

CREATE OR REPLACE FUNCTION public.reset_sequence(tablename text, columnname text)
 RETURNS void
 LANGUAGE plpgsql
AS $function$
DECLARE
    _sql VARCHAR := '';
BEGIN
    _sql := $$SELECT setval( pg_get_serial_sequence('$$ || tablename || $$', '$$ || columnname || $$'), (SELECT COALESCE(MAX($$ || columnname || $$),1) FROM $$ || tablename || $$), true)$$;
    EXECUTE _sql;
END;
$function$;

আশা করি এটি কারওর সাথে পুনরায় সেট করার ক্রমকে সহায়তা করবে!


কয়েক বছর পরে, আমি আপনার আপডেটটি লক্ষ্য করি এবং একটি উত্সাহ প্রদান করতে পপ করে :-)
সেমি

3

এই বিবৃতিটি প্রতিটি সিকোয়েন্সের সাথে যুক্ত টেবিল এবং কলামকে তালিকাবদ্ধ করে:

কোড:

    SELECT t.relname as related_table, 
           a.attname as related_column,
           s.relname as sequence_name
    FROM pg_class s 
      JOIN pg_depend d ON d.objid = s.oid 
      JOIN pg_class t ON d.objid = s.oid AND d.refobjid = t.oid 
      JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)
      JOIN pg_namespace n ON n.oid = s.relnamespace 
    WHERE s.relkind     = 'S' 

  AND n.nspname     = 'public'

আরও উত্তর এখানে লিঙ্ক দেখুন


2

পূর্ববর্তী উত্তরের উন্নতি:

select string_agg('select sequence_name, last_value from ' || relname, chr(13) || 'union' || chr(13) order by relname) 
from pg_class where relkind ='S'

3
দয়া করে কোনও ব্যাখ্যা ছাড়াই আপনার কোডটি রাখবেন না। এছাড়াও, যেহেতু আপনি বলেছেন যে আপনার কোডটি "পূর্ববর্তী উত্তরের উন্নতি", তাই আপনার এটিও কেন বলা হয়েছে তা আমাদের জানান। ওহ, হাল ছাড়বেন না, এবং তাই আপনাকে স্বাগতম!
জোয়েল

আমি কি সুনির্দিষ্ট কোডের পরিবর্তে একটি সংজ্ঞাহীন পাঠ্যের একটি পৃষ্ঠা লিখতে পারি (কয়েক লাইনের)?
আলেকজান্ডার রিয়াবভ 13

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

1

আংশিকভাবে পরীক্ষিত তবে বেশিরভাগ সম্পূর্ণ দেখায়।

select *
  from (select n.nspname,c.relname,
               (select substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
                  from pg_catalog.pg_attrdef d
                 where d.adrelid=a.attrelid
                   and d.adnum=a.attnum
                   and a.atthasdef) as def
          from pg_class c, pg_attribute a, pg_namespace n
         where c.relkind='r'
           and c.oid=a.attrelid
           and n.oid=c.relnamespace
           and a.atthasdef
           and a.atttypid=20) x
 where x.def ~ '^nextval'
 order by nspname,relname;

ক্রেডিট যেখানে creditণ দেওয়ার কথা ... এটি সিক্যুয়েন্সযুক্ত একটি টেবিলের একটি \ d থেকে লগ ইন করা এসকিউএল থেকে আংশিকভাবে বিপরীত হয়। আমি নিশ্চিত এটি আরও পরিষ্কার হতে পারে, তবে ওহে, পারফরম্যান্স কোনও উদ্বেগের বিষয় ছিল না।


1

হ্যাকের মতো, তবে এটি চেষ্টা করুন:

'সিলেক্ট' '' নির্বাচন করুন || পুনঃনামকরণ || '' 'ক্রম হিসাবে, শেষ থেকে' || পুনঃনামকরণ || 'ইউনিয়ন' থেকে pg_catolog.pg_class c যেখানে c.relkind IN ('S', '');

সর্বশেষ ইউনিয়নটি সরিয়ে ফলাফলটি কার্যকর করুন


1

ডিফল্ট ক্লজটি পার্সিংয়ের মাধ্যমে প্রতিটি টেবিলের প্রতিটি কলাম অনুসারে ক্রম পান। এই পদ্ধতিটি কলাম সিক্যুয়েন্সগুলি লিঙ্কযুক্ত এবং নির্ভরতাগুলি ব্যবহার করে না যা কিছু সিকোয়েন্সের জন্য উপস্থিত না থাকতে পারে তার তথ্য সরবরাহ করে। এমনকি pg_get_serial_sequence(sch.nspname||'.'||tbl.relname, col.attname)ফাংশনটি আমার জন্য সমস্ত সিক্যুয়েন্স পাওয়া যায় নি !

সমাধান:

SELECT
    seq_sch.nspname  AS sequence_schema
  , seq.relname      AS sequence_name
  , seq_use."schema" AS used_in_schema
  , seq_use."table"  AS used_in_table
  , seq_use."column" AS used_in_column
FROM pg_class seq
  INNER JOIN pg_namespace seq_sch ON seq_sch.oid = seq.relnamespace
  LEFT JOIN (
              SELECT
                  sch.nspname AS "schema"
                , tbl.relname AS "table"
                , col.attname AS "column"
                , regexp_split_to_array(
                      TRIM(LEADING 'nextval(''' FROM
                           TRIM(TRAILING '''::regclass)' FROM
                                pg_get_expr(def.adbin, tbl.oid, TRUE)
                           )
                      )
                      , '\.'
                  )           AS column_sequence
              FROM pg_class tbl --the table
                INNER JOIN pg_namespace sch ON sch.oid = tbl.relnamespace
                --schema
                INNER JOIN pg_attribute col ON col.attrelid = tbl.oid
                --columns
                INNER JOIN pg_attrdef def ON (def.adrelid = tbl.oid AND def.adnum = col.attnum) --default values for columns
              WHERE tbl.relkind = 'r' --regular relations (tables) only
                    AND col.attnum > 0 --regular columns only
                    AND def.adsrc LIKE 'nextval(%)' --sequences only
            ) seq_use ON (seq_use.column_sequence [1] = seq_sch.nspname AND seq_use.column_sequence [2] = seq.relname)
WHERE seq.relkind = 'S' --sequences only
ORDER BY sequence_schema, sequence_name;

নোট করুন যে 1 ক্রম একাধিক সারণীতে ব্যবহার করা যেতে পারে, তাই এটি এখানে একাধিক সারিতে তালিকাভুক্ত করা যেতে পারে।


0

আপনার সাহায্যের জন্য ধন্যবাদ.

এখানে pl / pgsql ফাংশন যা ডাটাবেসের প্রতিটি ক্রম আপডেট করে।

---------------------------------------------------------------------------------------------------------
--- Nom : reset_sequence
--- Description : Générique - met à jour les séquences au max de l'identifiant
---------------------------------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION reset_sequence() RETURNS void AS 
$BODY$
DECLARE _sql VARCHAR := '';
DECLARE result threecol%rowtype; 
BEGIN
FOR result IN 
WITH fq_objects AS (SELECT c.oid,n.nspname || '.' ||c.relname AS fqname ,c.relkind, c.relname AS relation FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace ),
    sequences AS (SELECT oid,fqname FROM fq_objects WHERE relkind = 'S'),
    tables    AS (SELECT oid, fqname FROM fq_objects WHERE relkind = 'r' )
SELECT
       s.fqname AS sequence,
       t.fqname AS table,
       a.attname AS column
FROM
     pg_depend d JOIN sequences s ON s.oid = d.objid
                 JOIN tables t ON t.oid = d.refobjid
                 JOIN pg_attribute a ON a.attrelid = d.refobjid and a.attnum = d.refobjsubid
WHERE
     d.deptype = 'a' 
LOOP
     EXECUTE 'SELECT setval('''||result.col1||''', COALESCE((SELECT MAX('||result.col3||')+1 FROM '||result.col2||'), 1), false);';
END LOOP;
END;$BODY$ LANGUAGE plpgsql;

SELECT * FROM reset_sequence();

0

এখানে সিকোয়েন্স নামের পাশে স্কিমা নাম রয়েছে এমন আরও একটি

select nspname,relname from pg_class c join pg_namespace n on c.relnamespace=n.oid where relkind = 'S' order by nspname

0

এই ফাংশনটি প্রতিটি অনুক্রমের শেষ_মুল্যটি দেখায়।

এটি একটি 2 কলামের টেবিলকে আউটপুট করে যা ক্রমটির নাম বলে প্লাস এটি সর্বশেষ উত্পাদিত মান।

drop function if exists public.show_sequence_stats();
CREATE OR REPLACE FUNCTION public.show_sequence_stats()
    RETURNS TABLE(tablename text, last_value bigint) 
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE 
    ROWS 1000
AS $BODY$
declare r refcursor; rec record; dynamic_query varchar;
        BEGIN
            dynamic_query='select tablename,last_value from (';
            open r for execute 'select nspname,relname from pg_class c join pg_namespace n on c.relnamespace=n.oid where relkind = ''S'' order by nspname'; 
            fetch next from r into rec;
            while found 
            loop
                dynamic_query=dynamic_query || 'select '''|| rec.nspname || '.' || rec.relname ||''' "tablename",last_value from ' || rec.nspname || '.' || rec.relname || ' union all ';
                fetch next from r into rec; 
            end loop;
            close r; 
            dynamic_query=rtrim(dynamic_query,'union all') || ') x order by last_value desc;';
            return query execute dynamic_query;
        END;
$BODY$;

select * from show_sequence_stats();

0

ধরে নেওয়া যাক exec()ফাংশন এই পোস্টে ঘোষিত https://stackoverflow.com/a/46721603/653539 , একসঙ্গে তাদের শেষ মান ক্রম একক ক্যোয়ারী ব্যবহার করে সংগৃহীত হতে পারে:

select s.sequence_schema, s.sequence_name,
  (select * from exec('select last_value from ' || s.sequence_schema || '.' || s.sequence_name) as e(lv bigint)) last_value
from information_schema.sequences s

0
select sequence_name, (xpath('/row/last_value/text()', xml_count))[1]::text::int as last_value
from (
    select sequence_schema,
            sequence_name,         
            query_to_xml(format('select last_value from %I.%I', sequence_schema, sequence_name), false, true, '') as xml_count
    from information_schema.sequences
    where sequence_schema = 'public'
) new_table order by last_value desc;

0

psqlএর সাথে সমস্ত ক্রমগুলির তালিকা পেতে কীভাবে ব্যবহার করতে হয় তার একটি উদাহরণ এখানে দেওয়া হয়েছে last_value:

psql -U <username> -d <database> -t -c "SELECT 'SELECT ''' || c.relname || ''' as sequence_name, last_value FROM ' || c.relname || ';' FROM pg_class c WHERE (c.relkind = 'S')" | psql -U <username> -d <database> -t

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