একটি বহুভাষার ডাটাবেসের জন্য স্কিমা


235

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

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

CREATE TABLE T_PRODUCT (
  NAME        NVARCHAR(50),
  DESCRIPTION NTEXT,
  PRICE       NUMBER(18, 2)
)

আমি NAME এবং বর্ণনামূলক কলামে বহুভাষিক পাঠ্য সমর্থন করার জন্য তিনটি পদ্ধতির কথা ভাবতে পারি:

  1. প্রতিটি ভাষার জন্য পৃথক কলাম

    আমরা যখন সিস্টেমে একটি নতুন ভাষা যুক্ত করব, তখন অনুবাদিত পাঠ্য সংরক্ষণ করতে আমাদের অবশ্যই অতিরিক্ত কলাম তৈরি করতে হবে:

    CREATE TABLE T_PRODUCT (
      NAME_EN        NVARCHAR(50),
      NAME_DE        NVARCHAR(50),
      NAME_SP        NVARCHAR(50),
      DESCRIPTION_EN NTEXT,
      DESCRIPTION_DE NTEXT,
      DESCRIPTION_SP NTEXT,
      PRICE          NUMBER(18,2)
    )
  2. প্রতিটি ভাষার জন্য কলাম সহ অনুবাদ টেবিল

    অনুবাদিত পাঠ্য সংরক্ষণ করার পরিবর্তে, অনুবাদ টেবিলের জন্য কেবল একটি বিদেশী কী সংরক্ষণ করা হয়। অনুবাদ সারণীতে প্রতিটি ভাষার জন্য একটি কলাম থাকে।

    CREATE TABLE T_PRODUCT (
      NAME_FK        int,
      DESCRIPTION_FK int,
      PRICE          NUMBER(18, 2)
    )
    
    CREATE TABLE T_TRANSLATION (
      TRANSLATION_ID,
      TEXT_EN NTEXT,
      TEXT_DE NTEXT,
      TEXT_SP NTEXT
    )
  3. প্রতিটি ভাষার জন্য সারি সহ অনুবাদ টেবিল

    অনুবাদিত পাঠ্য সংরক্ষণ করার পরিবর্তে, অনুবাদ টেবিলের জন্য কেবল একটি বিদেশী কী সংরক্ষণ করা হয়। অনুবাদ সারণীতে কেবল একটি কী থাকে এবং একটি পৃথক সারণিতে একটি ভাষাতে প্রতিটি অনুবাদের জন্য একটি সারি থাকে।

    CREATE TABLE T_PRODUCT (
      NAME_FK        int,
      DESCRIPTION_FK int,
      PRICE          NUMBER(18, 2)
    )
    
    CREATE TABLE T_TRANSLATION (
      TRANSLATION_ID
    )
    
    CREATE TABLE T_TRANSLATION_ENTRY (
      TRANSLATION_FK,
      LANGUAGE_FK,
      TRANSLATED_TEXT NTEXT
    )
    
    CREATE TABLE T_TRANSLATION_LANGUAGE (
      LANGUAGE_ID,
      LANGUAGE_CODE CHAR(2)
    )

প্রতিটি সমাধানের পক্ষে মতামত রয়েছে এবং আমি জানতে চাই যে এই পদ্ধতির সাথে আপনার অভিজ্ঞতাগুলি কী, আপনি কী সুপারিশ করেন এবং কীভাবে আপনি একটি বহুভাষিক ডাটাবেস স্কিমা ডিজাইন করবেন about



3
আপনি এই লিঙ্কটি চেক করতে পারেন: gsdesign.ro/blog/m Multilanglang-- ডেটাবেস- ডিজাইন- অ্যাপ্লিকেশন মন্তব্য পড়া খুব সহায়ক যদিও
ফারিদ Alnamrouti

3
LANGUAGE_CODEপ্রাকৃতিক কী, এড়ানো LANGUAGE_ID
gavenkoa

1
আমি ইতিমধ্যে 2 এবং 3 দেখেছি / ব্যবহার করেছি, আমি তাদের প্রস্তাব দিই না, আপনি অনাথ সারি দিয়ে সহজেই শেষ করেন। @ সানওয়াইকিং ডিজাইনটি আরও ভাল আইএমও দেখায়
Guillaume86

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

উত্তর:


113

প্রতিটি অনুবাদযোগ্য টেবিলের জন্য সম্পর্কিত অনুবাদ টেবিল থাকার বিষয়ে আপনি কী ভাবেন?

টেবিল তৈরি করুন_প্রোডাক্ট (pr_id ইন্ট, প্রাইস নম্বর (18, 2))

টেবিল তৈরি করুন T_PRODUCT_tr (pr_id INT এফকে, ল্যাঙ্গুয়েজ কোড ভারচার, প্রাইম নাম পাঠ্য, pr_descr পাঠ্য)

এইভাবে যদি আপনার একাধিক অনুবাদযোগ্য কলাম থাকে তবে এটি পেতে কেবলমাত্র একটি সংযুক্তি প্রয়োজন since যেহেতু আপনি কোনও অনুবাদ স্বয়ংক্রিয়ভাবে তৈরি করছেন না তবে সম্পর্কিত সম্পর্কিত অনুবাদগুলির সাথে আইটেমগুলি আমদানি করা আরও সহজ হতে পারে।

এর নেতিবাচক দিকটি হ'ল যদি আপনার কাছে একটি জটিল ভাষা ফ্যালব্যাক মেকানিজম থাকে তবে প্রতিটি অনুবাদ টেবিলের জন্য আপনার এটি প্রয়োগ করা প্রয়োজন - যদি আপনি এটি করার জন্য কিছু সঞ্চিত পদ্ধতির উপর নির্ভর করে থাকেন। আপনি যদি অ্যাপ থেকে এটি করেন তবে সম্ভবত সমস্যা হবে না be

আপনি কী ভাবছেন তা আমাকে জানান - আমি আমাদের পরবর্তী আবেদনের জন্য এই বিষয়ে সিদ্ধান্ত নিতে চলেছি। এখন পর্যন্ত আমরা আপনার ২ য় প্রকারটি ব্যবহার করেছি।


2
এই বিকল্পটি আমার বিকল্প এনআর 1 এর অনুরূপ তবে আরও ভাল। এটি এখনও রক্ষণাবেক্ষণ করা শক্ত এবং নতুন ভাষার জন্য নতুন সারণী তৈরি করা দরকার, তাই আমি এটি প্রয়োগ করতে নারাজ be
qbeuek

28
এটি কোনও নতুন ভাষার জন্য একটি নতুন টেবিলের প্রয়োজন নেই - আপনি নিজের নতুন ভাষার সাথে যথাযথ _ টিআর টেবিলে একটি নতুন সারি যুক্ত করুন, আপনি যদি নতুন অনুবাদযোগ্য টেবিল তৈরি করেন তবে আপনাকে কেবল একটি নতুন _tr টেবিল তৈরি করতে হবে

3
আমি অনুভব করি যে এটি একটি ভাল পদ্ধতি। অন্যান্য পদ্ধতির জন্য প্রচুর বাম সংযুক্ত হওয়া প্রয়োজন এবং আপনি যখন একাধিক টেবিলগুলিতে যোগ দিচ্ছেন যে তাদের প্রত্যেকের 3 স্তরের গভীর মত অনুবাদ রয়েছে এবং প্রত্যেকের 3 টি ক্ষেত্র রয়েছে আপনার কেবল 3 টি 3 9 বাকী কেবল অনুবাদে যোগ দেয় .. অন্যান্য বুদ্ধিমান 3. এটিও প্রতিবন্ধকতা ইত্যাদি যুক্ত করা সহজ এবং আমি নিখুঁতভাবে অনুসন্ধান করা আরও অনুরোধযোগ্য।
গরিলাএপ

1
যখন T_PRODUCT1 মিলিয়ন সারি থাকবে, T_PRODUCT_trতখন 2 মিলিয়ন থাকতে পারে? এটি কি বর্গ দক্ষতা কমিয়ে দেবে?
মিথিল

1
@ মিথ্রিল যেভাবেই আপনার কাছে 2 মিলিয়ন সারি রয়েছে। কমপক্ষে আপনার এই পদ্ধতির সাথে যোগ দেওয়ার দরকার নেই।
ডেভিড ডি

56

এটি একটি আকর্ষণীয় ইস্যু, সুতরাং আসুন শুরু করা যাক।

আসুন শুরু করা যাক পদ্ধতি 1 এর সমস্যাগুলি দ্বারা:
সমস্যা: আপনি গতি বাঁচাতে অস্বীকার করছেন।
এসকিউএল-তে (পোস্টারগ্রিসকুল ছাড়া হস্টোর সহ) আপনি কোনও প্যারামিটার ভাষা পাস করতে পারবেন না এবং বলবেন:

SELECT ['DESCRIPTION_' + @in_language]  FROM T_Products

সুতরাং আপনাকে এটি করতে হবে:

SELECT 
    Product_UID 
    ,
    CASE @in_language 
        WHEN 'DE' THEN DESCRIPTION_DE 
        WHEN 'SP' THEN DESCRIPTION_SP 
        ELSE DESCRIPTION_EN 
    END AS Text 
FROM T_Products 

যার অর্থ আপনি যদি কোনও নতুন ভাষা যুক্ত করেন তবে আপনাকে আপনার সমস্ত প্রশ্নের পরিবর্তন করতে হবে। এটি স্বাভাবিকভাবেই "ডায়নামিক এসকিউএল" ব্যবহারের দিকে পরিচালিত করে, তাই আপনাকে আপনার সমস্ত প্রশ্নের পরিবর্তন করতে হবে না।

এটি সাধারণত এর মতো কিছুতে পরিণতি দেয় (এবং এটি দর্শন বা টেবিল-মূল্যবান ফাংশনগুলিতে উপায় হিসাবে ব্যবহার করা যায় না, যদি আপনাকে রিপোর্টিংয়ের তারিখটি ফিল্টার করার দরকার হয় তবে এটি আসলেই একটি সমস্যা)

CREATE PROCEDURE [dbo].[sp_RPT_DATA_BadExample]
     @in_mandant varchar(3) 
    ,@in_language varchar(2) 
    ,@in_building varchar(36) 
    ,@in_wing varchar(36) 
    ,@in_reportingdate varchar(50) 
AS
BEGIN
    DECLARE @sql varchar(MAX), @reportingdate datetime

    -- Abrunden des Eingabedatums auf 00:00:00 Uhr
    SET @reportingdate = CONVERT( datetime, @in_reportingdate) 
    SET @reportingdate = CAST(FLOOR(CAST(@reportingdate AS float)) AS datetime)
    SET @in_reportingdate = CONVERT(varchar(50), @reportingdate) 

    SET NOCOUNT ON;


    SET @sql='SELECT 
         Building_Nr AS RPT_Building_Number 
        ,Building_Name AS RPT_Building_Name 
        ,FloorType_Lang_' + @in_language + ' AS RPT_FloorType 
        ,Wing_No AS RPT_Wing_Number 
        ,Wing_Name AS RPT_Wing_Name 
        ,Room_No AS RPT_Room_Number 
        ,Room_Name AS RPT_Room_Name 
    FROM V_Whatever 
    WHERE SO_MDT_ID = ''' + @in_mandant + ''' 

    AND 
    ( 
        ''' + @in_reportingdate + ''' BETWEEN CAST(FLOOR(CAST(Room_DateFrom AS float)) AS datetime) AND Room_DateTo 
        OR Room_DateFrom IS NULL 
        OR Room_DateTo IS NULL 
    ) 
    '

    IF @in_building    <> '00000000-0000-0000-0000-000000000000' SET @sql=@sql + 'AND (Building_UID  = ''' + @in_building + ''') '
    IF @in_wing    <> '00000000-0000-0000-0000-000000000000' SET @sql=@sql + 'AND (Wing_UID  = ''' + @in_wing + ''') '

    EXECUTE (@sql) 

END


GO

এটির সাথে সমস্যাটি হ'ল
) তারিখ-বিন্যাসটি খুব ভাষা-নির্দিষ্ট, তাই আপনি যদি সেখানে আইএসও ফর্ম্যাটে ইনপুট না রাখেন (তবে গড় বাগানের বিভিন্ন ধরণের প্রোগ্রামার সাধারণত না করে এবং আপনার ক্ষেত্রে সমস্যা হয়) একটি প্রতিবেদন ব্যবহারকারী নিশ্চিত করে যে আপনার জন্য নরক কিছু করবে না, এমনকি যদি তা স্পষ্টভাবে করার জন্য নির্দেশিত হয়)।
এবং
খ) সর্বাধিক উল্লেখযোগ্যভাবে , আপনি যেকোন ধরণের সিনট্যাক্স চেকিং .িলা করেন । যদি <insert name of your "favourite" person here>স্কিমাটি পরিবর্তন করে কারণ হঠাৎ করে উইং পরিবর্তনের প্রয়োজনীয়তা এবং নতুন একটি টেবিল তৈরি করা হয়, পুরানোটি বাকি থাকে তবে রেফারেন্স ফিল্ডটির নাম পরিবর্তন করা হয়, আপনি কোনও ধরণের সতর্কতা পান না। উইং প্যারামিটার (==> গাইড.empty) বাছাই । তবে হঠাৎ, যখন প্রকৃত ব্যবহারকারী প্রকৃতপক্ষে একটি ডানা নির্বাচন করে ==>বুম বাছাই না করে আপনি যখন এটি চালান তখনও একটি প্রতিবেদন কাজ করে । এই পদ্ধতিটি কোনও ধরণের পরীক্ষাকে পুরোপুরি বিরতি দেয়।


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


পদ্ধতি 3:
সমস্ত অনুবাদগুলির জন্য একটি টেবিল: অসুবিধা: আপনার অনুবাদ করতে চান এমন ক্ষেত্রগুলির জন্য পণ্য টেবিলে আপনাকে n বিদেশী কীগুলি সংরক্ষণ করতে হবে। অতএব, আপনাকে এন ক্ষেত্রের সাথে যোগ দিতে হবে। অনুবাদ টেবিলটি যখন বিশ্বব্যাপী হয়, তখন এর অনেকগুলি এন্ট্রি থাকে এবং ধীরে ধীরে যোগ দেয়। এছাড়াও, আপনাকে সর্বদা n টি ক্ষেত্রের জন্য টি টাইপআরএলসেশনে সারণিতে যোগ দিতে হবে। এটি বেশ ওভারহেড। এখন, যখন আপনার অবশ্যই গ্রাহক প্রতি কাস্টম অনুবাদগুলি সমন্বিত করতে হবে? আপনাকে একটি অতিরিক্ত টেবিলের সাথে আরও 2x এন যোগ দিতে হবে। আপনার যদি যোগ দিতে হয় তবে 2x2xn = 4n অতিরিক্ত যোগ দিয়ে 10 টি টেবিল বলুন, কী গোলমাল! এছাড়াও, এই নকশাটি 2 টি টেবিলের সাথে একই অনুবাদ ব্যবহার সম্ভব করে তোলে। আমি যদি একটি টেবিলের আইটেমের নামটি পরিবর্তন করি তবে আমি কি প্রতিটি টেবিলের পাশাপাশি অন্য এক টেবিলে কোনও এন্ট্রি পরিবর্তন করতে চাই?

এছাড়াও আপনি টেবিলটি আর মুছতে এবং পুনরায় সন্নিবেশ করতে পারবেন না, কারণ এখন পণ্য টেবিলগুলিতে বিদেশী কী রয়েছে ... আপনি অবশ্যই এফকে সেট করতে বাদ দিতে <insert name of your "favourite" person here>পারেন , এবং তারপরে টেবিলটি মুছতে পারেন এবং পুনরায় সন্নিবেশ করতে পারেন because newid () সহ সমস্ত এন্ট্রি [বা সন্নিবেশে আইডি নির্দিষ্ট করে, তবে পরিচয়-সন্নিবেশ বন্ধ রয়েছে ], এবং এটি (এবং করবে) সত্যই শীঘ্রই ডেটা-আবর্জনা (এবং নাল-রেফারেন্স ব্যতিক্রম) এ নিয়ে যাবে।


পদ্ধতি 4 (তালিকাভুক্ত নয়): ডাটাবেসে একটি এক্সএমএল ক্ষেত্রে সমস্ত ভাষা সংরক্ষণ করা। যেমন

-- CREATE TABLE MyTable(myfilename nvarchar(100) NULL, filemeta xml NULL )


;WITH CTE AS 
(
      -- INSERT INTO MyTable(myfilename, filemeta) 
      SELECT 
             'test.mp3' AS myfilename 
            --,CONVERT(XML, N'<?xml version="1.0" encoding="utf-16" standalone="yes"?><body>Hello</body>', 2) 
            --,CONVERT(XML, N'<?xml version="1.0" encoding="utf-16" standalone="yes"?><body><de>Hello</de></body>', 2) 
            ,CONVERT(XML
            , N'<?xml version="1.0" encoding="utf-16" standalone="yes"?>
<lang>
      <de>Deutsch</de>
      <fr>Français</fr>
      <it>Ital&amp;iano</it>
      <en>English</en>
</lang>
            ' 
            , 2 
            ) AS filemeta 
) 

SELECT 
       myfilename
      ,filemeta
      --,filemeta.value('body', 'nvarchar') 
      --, filemeta.value('.', 'nvarchar(MAX)') 

      ,filemeta.value('(/lang//de/node())[1]', 'nvarchar(MAX)') AS DE
      ,filemeta.value('(/lang//fr/node())[1]', 'nvarchar(MAX)') AS FR
      ,filemeta.value('(/lang//it/node())[1]', 'nvarchar(MAX)') AS IT
      ,filemeta.value('(/lang//en/node())[1]', 'nvarchar(MAX)') AS EN
FROM CTE 

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

filemeta.value('(/lang//' + @in_language + '/node())[1]', 'nvarchar(MAX)') AS bla

এবং আপনি এর মতো মান আপডেট করতে পারেন:

UPDATE YOUR_TABLE
SET YOUR_XML_FIELD_NAME.modify('replace value of (/lang/de/text())[1] with "&quot;I am a ''value &quot;"')
WHERE id = 1 

আপনি কোথায় প্রতিস্থাপন করতে পারেন /lang/de/...সঙ্গে'.../' + @in_language + '/...'

পোস্টগ্রি হস্টোরের মতো ধরণের, এক্সএমএল পার্সিংয়ের ওভারহেডের কারণে (পিজি হস্টোরের কোনও এসোসিয়েটিভ অ্যারে থেকে এন্ট্রি পড়ার পরিবর্তে) এটি অনেক ধীর হয়ে যায় প্লাস xML এনকোডিংটি দরকারী হওয়াতে খুব বেদনাদায়ক করে তোলে।


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

এই কর্মগুলি দেখার জন্য একটি উদাহরণ তৈরি করি:

প্রথমে সারণী তৈরি করুন:

CREATE TABLE dbo.T_Languages
(
     Lang_ID int NOT NULL
    ,Lang_NativeName national character varying(200) NULL
    ,Lang_EnglishName national character varying(200) NULL
    ,Lang_ISO_TwoLetterName character varying(10) NULL
    ,CONSTRAINT PK_T_Languages PRIMARY KEY ( Lang_ID )
);

GO




CREATE TABLE dbo.T_Products
(
     PROD_Id int NOT NULL
    ,PROD_InternalName national character varying(255) NULL
    ,CONSTRAINT PK_T_Products PRIMARY KEY ( PROD_Id )
); 

GO



CREATE TABLE dbo.T_Products_i18n
(
     PROD_i18n_PROD_Id int NOT NULL
    ,PROD_i18n_Lang_Id int NOT NULL
    ,PROD_i18n_Text national character varying(200) NULL
    ,CONSTRAINT PK_T_Products_i18n PRIMARY KEY (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id)
);

GO

-- ALTER TABLE dbo.T_Products_i18n  WITH NOCHECK ADD  CONSTRAINT FK_T_Products_i18n_T_Products FOREIGN KEY(PROD_i18n_PROD_Id)
ALTER TABLE dbo.T_Products_i18n  
    ADD CONSTRAINT FK_T_Products_i18n_T_Products 
    FOREIGN KEY(PROD_i18n_PROD_Id)
    REFERENCES dbo.T_Products (PROD_Id)
ON DELETE CASCADE 
GO

ALTER TABLE dbo.T_Products_i18n CHECK CONSTRAINT FK_T_Products_i18n_T_Products
GO

ALTER TABLE dbo.T_Products_i18n 
    ADD  CONSTRAINT FK_T_Products_i18n_T_Languages 
    FOREIGN KEY( PROD_i18n_Lang_Id )
    REFERENCES dbo.T_Languages( Lang_ID )
ON DELETE CASCADE 
GO

ALTER TABLE dbo.T_Products_i18n CHECK CONSTRAINT FK_T_Products_i18n_T_Products
GO



CREATE TABLE dbo.T_Products_i18n_Cust
(
     PROD_i18n_Cust_PROD_Id int NOT NULL
    ,PROD_i18n_Cust_Lang_Id int NOT NULL
    ,PROD_i18n_Cust_Text national character varying(200) NULL
    ,CONSTRAINT PK_T_Products_i18n_Cust PRIMARY KEY ( PROD_i18n_Cust_PROD_Id, PROD_i18n_Cust_Lang_Id )
);

GO

ALTER TABLE dbo.T_Products_i18n_Cust  
    ADD CONSTRAINT FK_T_Products_i18n_Cust_T_Languages 
    FOREIGN KEY(PROD_i18n_Cust_Lang_Id)
    REFERENCES dbo.T_Languages (Lang_ID)

ALTER TABLE dbo.T_Products_i18n_Cust CHECK CONSTRAINT FK_T_Products_i18n_Cust_T_Languages

GO



ALTER TABLE dbo.T_Products_i18n_Cust  
    ADD CONSTRAINT FK_T_Products_i18n_Cust_T_Products 
    FOREIGN KEY(PROD_i18n_Cust_PROD_Id)
REFERENCES dbo.T_Products (PROD_Id)
GO

ALTER TABLE dbo.T_Products_i18n_Cust CHECK CONSTRAINT FK_T_Products_i18n_Cust_T_Products
GO

তারপরে ডেটা পূরণ করুন

DELETE FROM T_Languages;
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (1, N'English', N'English', N'EN');
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (2, N'Deutsch', N'German', N'DE');
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (3, N'Français', N'French', N'FR');
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (4, N'Italiano', N'Italian', N'IT');
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (5, N'Russki', N'Russian', N'RU');
INSERT INTO T_Languages (Lang_ID, Lang_NativeName, Lang_EnglishName, Lang_ISO_TwoLetterName) VALUES (6, N'Zhungwen', N'Chinese', N'ZH');

DELETE FROM T_Products;
INSERT INTO T_Products (PROD_Id, PROD_InternalName) VALUES (1, N'Orange Juice');
INSERT INTO T_Products (PROD_Id, PROD_InternalName) VALUES (2, N'Apple Juice');
INSERT INTO T_Products (PROD_Id, PROD_InternalName) VALUES (3, N'Banana Juice');
INSERT INTO T_Products (PROD_Id, PROD_InternalName) VALUES (4, N'Tomato Juice');
INSERT INTO T_Products (PROD_Id, PROD_InternalName) VALUES (5, N'Generic Fruit Juice');

DELETE FROM T_Products_i18n;
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (1, 1, N'Orange Juice');
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (1, 2, N'Orangensaft');
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (1, 3, N'Jus d''Orange');
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (1, 4, N'Succo d''arancia');
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (2, 1, N'Apple Juice');
INSERT INTO T_Products_i18n (PROD_i18n_PROD_Id, PROD_i18n_Lang_Id, PROD_i18n_Text) VALUES (2, 2, N'Apfelsaft');

DELETE FROM T_Products_i18n_Cust;
INSERT INTO T_Products_i18n_Cust (PROD_i18n_Cust_PROD_Id, PROD_i18n_Cust_Lang_Id, PROD_i18n_Cust_Text) VALUES (1, 2, N'Orangäsaft'); -- Swiss German, if you wonder

এবং তারপরে ডেটাটি জিজ্ঞাসা করুন:

DECLARE @__in_lang_id int
SET @__in_lang_id = (
    SELECT Lang_ID
    FROM T_Languages
    WHERE Lang_ISO_TwoLetterName = 'DE'
)

SELECT 
     PROD_Id 
    ,PROD_InternalName -- Default Fallback field (internal name/one language only setup), just in ResultSet for demo-purposes
    ,PROD_i18n_Text  -- Translation text, just in ResultSet for demo-purposes
    ,PROD_i18n_Cust_Text  -- Custom Translations (e.g. per customer) Just in ResultSet for demo-purposes
    ,COALESCE(PROD_i18n_Cust_Text, PROD_i18n_Text, PROD_InternalName) AS DisplayText -- What we actually want to show 
FROM T_Products 

LEFT JOIN T_Products_i18n 
    ON PROD_i18n_PROD_Id = T_Products.PROD_Id 
    AND PROD_i18n_Lang_Id = @__in_lang_id 

LEFT JOIN T_Products_i18n_Cust 
    ON PROD_i18n_Cust_PROD_Id = T_Products.PROD_Id
    AND PROD_i18n_Cust_Lang_Id = @__in_lang_id

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

যাইহোক, আপনি যদি একটি পূর্ণসংখ্যার আইডি ব্যবহার করেন তবে আপনি নমনীয় এবং পরবর্তী সময়ে আপনার পদ্ধতিটি পরিবর্তন করতে পারেন।
এবং আপনার সেই পূর্ণসংখ্যাটি ব্যবহার করা উচিত, কারণ বোটড ডিবি ডিজাইনের চেয়ে বিরক্তিজনক, ধ্বংসাত্মক এবং ঝামেলা আর কিছুই নেই।

আরও দেখুন বোঝায় যা RFC 5646 , আইএসও 639-2 ,

এবং, যদি আপনি এখনও "আমরা" কেবলমাত্র "শুধুমাত্র একটি সংস্কৃতি" (যেমন আমেরিকা যুক্তরাষ্ট্রের মতো) এর জন্য আমাদের অ্যাপ্লিকেশন তৈরি করে থাকি - সুতরাং আমার অতিরিক্ত অতিরিক্ত পূর্ণসংখ্যার প্রয়োজন নেই, তবে এটি উল্লেখ করার জন্য এটি ভাল সময় এবং জায়গা হবে আইএএনএ ভাষার ট্যাগ , তাই না?
কারণ তারা এভাবে চলে:

de-DE-1901
de-DE-1996

এবং

de-CH-1901
de-CH-1996

(১৯৯ in সালে একটি অর্থোগ্রাফিক সংস্কার ছিল ...) অভিধানে কোনও শব্দ ভুল বানান থাকলে এটি অনুসন্ধান করার চেষ্টা করুন; আইনী এবং পাবলিক সার্ভিস পোর্টালগুলির সাথে ডিল করার অ্যাপ্লিকেশনগুলিতে এটি অত্যন্ত গুরুত্বপূর্ণ হয়ে ওঠে।
আরও গুরুত্বপূর্ণভাবে, এমন অঞ্চলগুলি রয়েছে যা সিরিলিক থেকে লাতিন বর্ণমালায় পরিবর্তিত হচ্ছে, যা কিছু অস্পষ্ট orthography সংস্কারের অতিমাত্রায় উপদ্রব চেয়ে আরও বেশি ঝামেলা হতে পারে, এজন্য আপনি কোন দেশে বাস করছেন তার উপর নির্ভর করে এটিও একটি গুরুত্বপূর্ণ বিবেচ্য বিষয় হতে পারে। একটি উপায় বা অন্য উপায়, কেবল সেখানে যদি সেই পূর্ণসংখ্যাটি রাখা ভাল ...

সম্পাদনা করুন:
এবং ON DELETE CASCADE পরে যুক্ত করে

REFERENCES dbo.T_Products( PROD_Id )

আপনি কেবল বলতে পারেন:, DELETE FROM T_Productsএবং কোনও বিদেশী কী লঙ্ঘন পাবেন না।

কোলেশন হিসাবে, আমি এটি এর মতো করব:

ক) আপনার নিজস্ব ডাল
খ) ভাষা সারণীতে পছন্দসই কলেজের নাম সংরক্ষণ করুন

আপনি কলিকেশনগুলি তাদের নিজস্ব টেবিলে রাখতে পারেন, যেমন:

SELECT * FROM sys.fn_helpcollations() 
WHERE description LIKE '%insensitive%'
AND name LIKE '%german%' 

গ) আপনার auth.user.language তথ্যটিতে কলেজের নাম উপলব্ধ রয়েছে

)) আপনার এসকিউএল এভাবে লিখুন:

SELECT 
    COALESCE(GRP_Name_i18n_cust, GRP_Name_i18n, GRP_Name) AS GroupName 
FROM T_Groups 

ORDER BY GroupName COLLATE {#COLLATION}

ঙ) তারপরে, আপনি আপনার ডালে এটি করতে পারেন:

cmd.CommandText = cmd.CommandText.Replace("{#COLLATION}", auth.user.language.collation)

যা আপনাকে এই নিখুঁতভাবে রচিত এসকিউএল-কোয়েরি দেবে

SELECT 
    COALESCE(GRP_Name_i18n_cust, GRP_Name_i18n, GRP_Name) AS GroupName 
FROM T_Groups 

ORDER BY GroupName COLLATE German_PhoneBook_CI_AI

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

2
@ ইউজিন ইভডোকিমভ: হ্যাঁ, তবে "অর্ডার বাই" সর্বদা একটি সমস্যা হতে চলেছে, কারণ আপনি এটিকে পরিবর্তনশীল হিসাবে নির্দিষ্ট করতে পারবেন না। আমার পন্থাটি হ'ল ভাষা সারণীতে কলেজের নাম সংরক্ষণ করুন এবং এটি ব্যবহারকারীর ইনফোনটিতে থাকা উচিত। তারপরে, প্রতিটি এসকিউএল-বিবৃতিতে আপনি COLUMN_NAME OR # সমষ্টি ol এর মাধ্যমে অর্ডার বলতে পারেন, এবং তারপরে আপনি আপনার ডালের প্রতিস্থাপন করতে পারেন (cmd.CommandText = cmd.CommandText.Replace ("{# COLLATION}", auth.user)। ল্যাঙ্গুয়েজ কোলেশন) বিকল্প হিসাবে, আপনি আপনার অ্যাপ্লিকেশন কোডটি বাছাই করতে পারেন, যেমন লিনকিউ ব্যবহার করে This এটি আপনার ডাটাবেস থেকে কিছু প্রসেসিং লোডও নিতে পারে reports রিপোর্টের জন্য রিপোর্টটি যেভাবেই হোক বাছাই করে নিতে পারে
স্টেফান স্টেইগার

oo এটি অবশ্যই আমি দেখেছি দীর্ঘতম SO উত্তর এবং আমি দেখেছি লোকেরা উত্তরে পুরো প্রোগ্রাম তৈরি করে। তুমি ভাল.
ডোমিনো

সম্পূর্ণভাবে SunWuKung এর সমাধান সম্মত করতে পারেন সবচেয়ে ভাল হয়
Domi

48

কয়েকটি কারণে তৃতীয় বিকল্পটি সেরা:

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

-Adam


1
আমি একমত, যদিও ব্যক্তিগতভাবে আমার কাছে প্রতিটি প্রধান টেবিলের জন্য স্থানীয় টেবিল থাকত, যাতে বিদেশী কীগুলি প্রয়োগ করা যায়।
নীল বার্নওয়েল

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

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

@ rics- আমি সম্মত, ভাল আপনি কি পরামর্শ ...?
সাবের

@ অ্যাডাম- আমি বিভ্রান্ত, সম্ভবত আমি ভুল বুঝেছি। আপনি তৃতীয়টির পরামর্শ দিয়েছেন, তাই না? দয়া করে এটিকে আরও বিশদে ব্যাখ্যা করুন যে এই টেবিলগুলির মধ্যে সম্পর্কগুলি কীভাবে হবে? আপনার অর্থ আমরা ডিবিতে প্রতিটি টেবিলের জন্য অনুবাদ এবং অনুবাদএন্ট্রি টেবিলগুলি প্রয়োগ করতে হবে?
সাবের

9

এই উদাহরণটি একবার দেখুন:

PRODUCTS (
    id   
    price
    created_at
)

LANGUAGES (
    id   
    title
)

TRANSLATIONS (
    id           (// id of translation, UNIQUE)
    language_id  (// id of desired language)
    table_name   (// any table, in this case PRODUCTS)
    item_id      (// id of item in PRODUCTS)
    field_name   (// fields to be translated)
    translation  (// translation text goes here)
)

আমি মনে করি ব্যাখ্যা করার দরকার নেই, কাঠামোটি নিজের বর্ণনা করে।


এটা ভাল. তবে আপনি কীভাবে অনুসন্ধান করবেন (উদাহরণস্বরূপ product_name)?
ইলুমিনাতি

আপনার নমুনার কোথাও আপনার লাইভ উদাহরণ রয়েছে? এটি ব্যবহার করে আপনি কি কোনও সমস্যা পেয়েছেন?
ডেভিড Létourneau

অবশ্যই, আমার কাছে বহুভাষিক রিয়েল এস্টেট প্রকল্প রয়েছে, আমরা 4 টি ভাষা সমর্থন করি। অনুসন্ধানটি কিছুটা জটিল তবে এটি দ্রুত। অবশ্যই বড় প্রকল্পগুলিতে এটি হওয়া দরকারের চেয়ে ধীর হতে পারে। ছোট বা মাঝারি প্রকল্পে এটি ঠিক আছে।
বাঁশমুরিক

8

আমি সাধারণত এই পদ্ধতির জন্য যাব (প্রকৃত স্ক্যুএল নয়), এটি আপনার শেষ বিকল্পের সাথে মিলে যায়।

table Product
productid INT PK, price DECIMAL, translationid INT FK

table Translation
translationid INT PK

table TranslationItem
translationitemid INT PK, translationid INT FK, text VARCHAR, languagecode CHAR(2)

view ProductView
select * from Product
inner join Translation
inner join TranslationItem
where languagecode='en'

কারণ সমস্ত অনুবাদযোগ্য পাঠ্য এক জায়গায় থাকা রক্ষণাবেক্ষণকে এত সহজ করে তোলে। কখনও কখনও অনুবাদগুলি অনুবাদ ব্যুরোতে আউটসোর্স করা হয়, আপনি তাদের কেবল একটি বড় রফতানি ফাইল প্রেরণ করতে পারেন, এবং ঠিক এটি সহজেই আমদানি করতে পারেন।


1
Translationটেবিল বা TranslationItem.translationitemidকলামটি কী উদ্দেশ্যে কাজ করে?
ড্যানম্যান

4

প্রযুক্তিগত বিশদ এবং সমাধানগুলিতে যাওয়ার আগে আপনার এক মিনিটের জন্য থামানো উচিত এবং প্রয়োজনীয়তা সম্পর্কে কয়েকটি প্রশ্ন জিজ্ঞাসা করা উচিত। উত্তরগুলি প্রযুক্তিগত সমাধানগুলিতে বিশাল প্রভাব ফেলতে পারে। এই জাতীয় প্রশ্নের উদাহরণগুলি হবেন:
- সমস্ত ভাষা কি সর্বদা ব্যবহৃত হবে?
- কারা এবং কবে বিভিন্ন ভাষার সংস্করণ সহ কলামগুলি পূরণ করবে?
- যখন কোনও ব্যবহারকারীর একটি পাঠ্যের একটি নির্দিষ্ট ভাষার প্রয়োজন হবে এবং সিস্টেমে কোনও নেই তখন কী ঘটে?
- কেবল পাঠ্যগুলি স্থানীয়করণ করতে হবে বা অন্যান্য আইটেমগুলিও রয়েছে (উদাহরণস্বরূপ PRICE $ এবং in এ সংরক্ষণ করা যেতে পারে কারণ সেগুলি আলাদা হতে পারে)


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

3

আমি স্থানীয়করণের জন্য কিছু টিপস সন্ধান করছি এবং এই বিষয়টি পেয়েছি। আমি ভাবছিলাম কেন এটি ব্যবহৃত হয়:

CREATE TABLE T_TRANSLATION (
   TRANSLATION_ID
)

সুতরাং আপনি ব্যবহারকারী 39603 এর মত কিছু পান:

table Product
productid INT PK, price DECIMAL, translationid INT FK

table Translation
translationid INT PK

table TranslationItem
translationitemid INT PK, translationid INT FK, text VARCHAR, languagecode CHAR(2)

view ProductView
select * from Product
inner join Translation
inner join TranslationItem
where languagecode='en'

আপনি কেবল টেবিলটি ছেড়ে দিতে পারবেন না অনুবাদটি বের করে ফেলুন যাতে আপনি এটি পান:

    table Product
    productid INT PK, price DECIMAL

    table ProductItem
    productitemid INT PK, productid INT FK, text VARCHAR, languagecode CHAR(2)

    view ProductView
    select * from Product
    inner join ProductItem
    where languagecode='en'

1
অবশ্যই। আমি ProductItemটেবিলে ফোন করতাম এমন কিছু ProductTextsবা ProductL10nযদিও। আরও বোধগম্য করে তোলে।
ড্যানম্যান

1

আমি র্যান্ডমাইজারের সাথে একমত আপনার কেন একটি টেবিল "অনুবাদ" দরকার তা আমি দেখতে পাচ্ছি না।

আমি মনে করি, এটি যথেষ্ট:

TA_product: ProductID, ProductPrice
TA_Language: LanguageID, Language
TA_Productname: ProductnameID, ProductID, LanguageID, ProductName

1

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

CREATE TABLE translation_entry (
      translation_id        int,
      language_id           int,
      table_name            nvarchar(200),
      table_column_name     nvarchar(200),
      table_row_id          bigint,
      translated_text       ntext
    )

    CREATE TABLE translation_language (
      id int,
      language_code CHAR(2)
    )   

0

"কোনটি সেরা" প্রকল্পের পরিস্থিতির ভিত্তিতে তৈরি। প্রথমটি নির্বাচন করা এবং বজায় রাখা সহজ, এবং সত্তা নির্বাচন করার সময় এটির টেবিলে যোগদানের প্রয়োজন হয় না বলেই অভিনয়টি সর্বোত্তম। যদি আপনি নিশ্চিত করে থাকেন যে আপনার পোজেক্টটি কেবলমাত্র 2 বা 3 টি ভাষা সমর্থন করে এবং এটি বাড়বে না, আপনি এটি ব্যবহার করতে পারেন।

দ্বিতীয়টি ওকি তবে এটি বোঝা এবং বজায় রাখা শক্ত। এবং পারফরম্যান্স প্রথম একের চেয়ে খারাপ।

শেষটি স্কেলাবিলিটিতে ভাল তবে পারফরম্যান্সে খারাপ। T_TRANSLATION_ENTRY টেবিলটি আরও বড় এবং বড় হয়ে উঠবে, আপনি যখন কিছু টেবিল থেকে সত্ত্বার তালিকা পুনরুদ্ধার করতে চান তখন ভয়াবহ।


0

এই নথিতে প্রতিটি পদ্ধতির সম্ভাব্য সমাধান এবং সুবিধা এবং অসুবিধাগুলি বর্ণনা করা হয়েছে। আমি "সারি স্থানীয়করণ" পছন্দ করি কারণ একটি নতুন ভাষা যুক্ত করার সময় আপনাকে ডিবি স্কিমাটি পরিবর্তন করতে হবে না।

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