অক্ষাংশ / দ্রাঘিমাংশের জন্য 8 দশমিক স্থানের জন্য কোন মাইএসকিউএল ডেটা টাইপ ব্যবহার করা উচিত?


256

আমি মানচিত্রের ডেটা, এবং Latitude/Longitude8 দশমিক জায়গায় প্রসারিত নিয়ে কাজ করছি । উদাহরণ স্বরূপ:

Latitude 40.71727401
Longitude -74.00898606

আমি গুগল নথিতে দেখেছি যা ব্যবহার করে:

lat FLOAT( 10, 6 ) NOT NULL,  
lng FLOAT( 10, 6 ) NOT NULL

কিন্তু, তাদের দশমিক স্থান কেবল 6. যেতে
বলা উচিৎ? ব্যবহারের FLOAT(10, 8)বা অন্য পদ্ধতি এই ডেটা সঞ্চয় করার তাই এটি সুনির্দিষ্ট জন্য বিবেচনা করা হয়। এটি মানচিত্রের গণনার সাথে ব্যবহার করা হবে। ধন্যবাদ!


4
আপনার কি সত্যই পৃথিবীর পৃষ্ঠের উপরে 1.1 মিমি অবধি মূল্য সঞ্চয় করতে হবে ? যদি তা হয়, তবে আপনি কেন প্রথম স্থানে ল্যাটল্যাংয়ে মানগুলি সংরক্ষণ করছেন?
ওভ্যাঙ্গেল


2
গুগল ডকটি ভুল! floatপ্রকারটি ব্যবহার করবেন না - যা কেবলমাত্র 7 সংখ্যক নির্ভুলতার সাথে রয়েছে। আপনার কমপক্ষে 9. টি দরকার আপনার 10 টি দরকার নেই - কোনও অদ্ভুত কারণে ডকগুলি বিয়োগ চিহ্নটিকে অঙ্ক হিসাবে গণনা করে। হয় হয়: double(9,6)বা decimal(9,6)
এরিয়েল

5
কত স্পষ্টতা আপনি কি সত্যিই প্রয়োজন? Dec দশমিক স্থান আপনাকে দু'জনকে একে অপরকে চুম্বন করার পার্থক্য করার জন্য যথাযথ নির্ভুলতা দেয়। 8 আপনার আঙ্গুলের কথা আলাদা করে বলতে পারে। FLOATদুটি আইটেমকে 1.7 মি (5.6 ফুট) আলাদা করে পৃথক করে। এগুলি সবাই "মানচিত্র" অ্যাপ্লিকেশনগুলির জন্য হাস্যকরভাবে অতিরিক্ত!
রিক জেমস

উত্তর:


594

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

অক্ষাংশ -৯০ থেকে +90 (ডিগ্রি) পর্যন্ত বিস্তৃত, সুতরাং ডেসিমাল (10, 8) এর জন্য ঠিক আছে তবে দ্রাঘিমাংশ -180 থেকে +180 (ডিগ্রি) পর্যন্ত বিস্তৃত সুতরাং আপনার ডেসিমাল (11, 8) প্রয়োজন। প্রথম সংখ্যাটি হ'ল সঞ্চিত অঙ্কের মোট সংখ্যা এবং দ্বিতীয়টি দশমিক বিন্দুর পরে সংখ্যা।

সংক্ষেপে: lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL

এই ব্যাখ্যা করে যে মাইএসকিউএল কীভাবে ভাসমান-পয়েন্ট ডেটা-টাইপগুলির সাথে কাজ করে।

আপডেট: মাইএসকিউএল স্পেসিয়াল ডেটা প্রকারকে সমর্থন করে এবং Pointএটি একটি একক মানের মূল্য যা ব্যবহার করা যেতে পারে। উদাহরণ:

CREATE TABLE `buildings` (
  `coordinate` POINT NOT NULL,
  /* Even from v5.7.5 you can define an index for it */
  SPATIAL INDEX `SPATIAL` (`coordinate`)
) ENGINE=InnoDB;

/* then for insertion you can */
INSERT INTO `buildings` 
(`coordinate`) 
VALUES
(POINT(40.71727401 -74.00898606));

11
সম্ভবত আমার উত্তরটি সঠিক শব্দটির অপব্যবহার করেছে, কারণ ডেসিমাল এখনও আপনি যে নির্ভুলতার সাথে দিচ্ছেন ঠিক ততটাই নির্ভুল। আমার পয়েন্ট যে এটি ছিল হয় যে সঠিক। অবশ্যই কিছু গণনা ত্রুটি প্রসারিত করে। আমার যদি একটি ডেসিমিয়াল এক্স থাকে তবে সাইন (x ^ 100) বন্ধ হয়ে যাচ্ছে। তবে যদি (ডিসিমাল (10, 8) বা ফ্লাট (10, 8) ব্যবহার করে আমি 0.3 / 3 গণনা করি তবে ডেসিমাল 0.100000000000 (সঠিক) দেয়, এবং ভাসা 0.100000003974 দেয় (8 ডিপি থেকে সঠিক, তবে গুণিত হলে ভুল হবে)। আমি বুঝতে পারি যে মূল পার্থক্যটি হল সংখ্যাগুলি কীভাবে সংরক্ষণ করা হয়। ডেসিমাল দশমিক সংখ্যা সংরক্ষণ করে যেখানে ফ্লোট বাইনারি আনুমানিকতা সঞ্চয় করে।
গ্যান্ডালিটার

1
নির্ভুলতার সন্দেহ দ্বারা, আমি ডাবল করতে যাচ্ছি।
রাতটা টাটা

1
8 দশমিক স্থান যথাক্রমে 1.1 মিমি (ইঞ্চির 1/16 এর কম)। অক্ষাংশ এবং দ্রাঘিমাংশের জন্য আপনি কেন কখনও এটির প্রয়োজন হবে?
ভেরটেক

1
ফেসবুকটি লেট-এর জন্য 12 দশমিক এবং এলএনজির জন্য 13 টি পর্যন্ত ব্যবহার করছে বলে মনে হচ্ছে। ভের্টেক লিখেছেন যে 8 দশমিক দশমিক 1 মিমি সমান; 7 এবং 6 সম্পর্কে কি? (আমি গণিতে ভাল নই)। আমি আপাতত দ্বিগুণ ব্যবহার করছি তবে ধরণের পরিবর্তন করে আমি দূরত্বের গণনা অর্জন করতে পারছি কিনা তা পরীক্ষা করতে চাই। ধন্যবাদ.
আলাইন জিলিংক

4
এই প্রশ্নের উত্তর ( gis.stackexchange.com/questions/8650/… ) আপনি অক্ষাংশ এবং দ্রাঘিমাংশের দশমিক স্থানের বিভিন্ন সংখ্যার সাথে যে নির্ভুলতা পেয়েছেন সে সম্পর্কে তথ্য দেয়।
গ্যান্ডালিটার

16

অতিরিক্তভাবে, আপনি দেখতে পাবেন যে floatমানগুলি বৃত্তাকার হয়।

// যেমন: প্রদত্ত মানগুলি 41.0473112,29.0077011

ভাসা (11,7) | দশমিক (11,7)
---------------------------
41.0473099 | 41.0473112
29.0077019 | 29.0077011


1
আপনি doubleডেটা টাইপ ব্যবহার করতে পারেন , যার যথার্থতা প্রয়োজন।
এরিয়েল

1
আমাকে একটি দরকারী মানচিত্র দেখান যা এই দুটি পয়েন্টকে আলাদা করতে পারে। আমি দাবি করি যে উভয় উপস্থাপনা "অযৌক্তিকভাবে সুনির্দিষ্ট"।
রিক জেমস

14

লারাভেলে মাইগ্রেশনের জন্য দশমিক কলাম প্রকার ব্যবহৃত হয়

$table->decimal('latitude', 10, 8);
$table->decimal('longitude', 11, 8);

আরও তথ্যের জন্য উপলব্ধ কলামের ধরণ দেখুন


7

আপনি স্বাক্ষরিত পূর্ণসংখ্য হিসাবে আপনার ডেটা-টাইপ সেট করতে পারেন। আপনি যখন এসকিউএলে স্থানাঙ্ক স্থানাঙ্ক করেন তখন আপনি ল্যাট * 10000000 এবং দীর্ঘ * 10000000 হিসাবে সেট করতে পারেন। এবং আপনি যখন দূরত্ব / ব্যাসার্ধের সাথে নির্বাচন করেন আপনি স্টোরেজ স্থানাঙ্কগুলি 10000000 এ ভাগ করবেন I (2 এক্স 2.67GHz সিপিইউ, 2 জিবি র‌্যাম, মাইএসকিউএল 5.5.49)


কোনটি দ্রুত? এটি করছেন বা ভাসমান বা দশমিক ব্যবহার করছেন?
দিনিদিনিজ

1
@ ডিনিডিনিজ - গতির পার্থক্য খুব কম। সারিগুলি আনার ফলে যে কোনও ডাটাবেস ক্রিয়াকলাপ ছড়িয়ে যায়।
রিক জেমস

10000000 কেন? দশমিক মানের পরে যদি এটিতে 6 টিরও বেশি সংখ্যা থাকে তবে কী হবে? অথবা এটি সর্বদা 6 দশমিক পয়েন্ট ফিরে আসবে।
মাহবুব মোর্শেদ

@ মাহবুবমর্শেদ - আপনার অর্থ 7 সংখ্যা - এখানে 7 টি শূন্য সংখ্যা দেখানো হয়েছে। তবে হ্যাঁ, এই কৌশলটি সর্বদা ঠিক 7 ডিজিট সংরক্ষণ করে চলেছে, আর নেই। (যদি 4-বাইট পূর্ণসংখ্যা ব্যবহার করা হয় তবে 7 সংখ্যার বেশি গুণকটি বাড়ানো যাবে না কারণ দ্রাঘিমাংশের মান 180 এর বেশি হতে পারে, এবং সাইন ইনগ্রিয়ারকে সর্বাধিক প্রবাহিত করা এড়াতে হবে)) একক নির্ভুলতা ফ্লোটে সঞ্চয় করার চেয়ে এটি 2 ডিজিট বেশি সুনির্দিষ্ট, বৃহত্তর দ্রাঘিমাংশের মানগুলিতে যার কেবলমাত্র দশমিক-পয়েন্ট-থেকে-ডান-দশমিক-পয়েন্ট থাকে which ); (179.99996 179,99998 থেকে অনেক দূরে নিরাপদে হয় 179,99998 এবং 179,99997 একই ভাসা মান হিসাবে সংরক্ষণ করতে পারে)।
ToolmakerSteve

এটি আমি যে কোনও জায়গায় দেখেছি সেরা বাণিজ্য। এখানে আমি ব্যবহার করতে এবং এটি লম্বা / ল্যাটের মানগুলির জন্য 4 বাইট স্বাক্ষরিত ইনট, দশমিক পয়েন্ট পরে 7 সংখ্যার সরবরাহ করে তা নিশ্চিত করতে কোড দেখায় (সুতরাং -180 .. + 180 এর মধ্যে)। ছোট আকারের (4 বি) -র দুর্দান্ত নির্ভুলতা (~ 1 সেমি)।
নির্মাতা স্টিভ

6

ভাসা ব্যবহার করবেন না ... এটি আপনার স্থানাঙ্কগুলির চারপাশে পরিণত হবে, যার ফলে কিছু অদ্ভুত ঘটনা ঘটবে।

দশমিক ব্যবহার করুন


4

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

জিওস্প্যাটিয়াল ডেটা ধরণের এবং স্থানিক বিশ্লেষণ ফাংশনগুলিতে মাইএসকিএল ডক্স পরীক্ষা করে দেখুন


4

আমি বিশ্বাস করি যে মাইএসকিউএল এ ল্যাট / এলএনজি সঞ্চয় করার সর্বোত্তম উপায় হল স্প্যাটাল সূচক সহ একটি পয়েন্ট কলাম (2 ডি ডেটাটাইপ) রাখা।

CREATE TABLE `cities` (
  `zip` varchar(8) NOT NULL,
  `country` varchar (2) GENERATED ALWAYS AS (SUBSTRING(`zip`, 1, 2)) STORED,
  `city` varchar(30) NOT NULL,
  `centre` point NOT NULL,
  PRIMARY KEY (`zip`),
  KEY `country` (`country`),
  KEY `city` (`city`),
  SPATIAL KEY `centre` (`centre`)
) ENGINE=InnoDB;


INSERT INTO `cities` (`zip`, `city`, `centre`) VALUES
('CZ-10000', 'Prague', POINT(50.0755381, 14.4378005));

0

রেলপথে রুবি স্থানান্তরিত করা

class CreateNeighborhoods < ActiveRecord::Migration[5.0]
  def change
    create_table :neighborhoods do |t|
      t.string :name
      t.decimal :latitude, precision: 15, scale: 13
      t.decimal :longitude, precision: 15, scale: 13
      t.references :country, foreign_key: true
      t.references :state, foreign_key: true
      t.references :city, foreign_key: true

      t.timestamps
    end
  end
end

এই সীমাটি -৯৯৯৯৯৯ সীমাতে থাকবে না? এটি প্রশান্ত মহাসাগরের অনেক কিছু বাদ দেয়!
রিক জেমস 4

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

(20,18)এছাড়াও +/- 99 এ শীর্ষে রয়েছে।
রিক জেমস

এটি নিখুঁত সত্য হিসাবে গ্রহণ করা উচিত নয় একটি উদাহরণ। আপনি অন্য দশমিক দশমিক নির্ভুলতা (20, 18) এবং আরও ব্যবহার করতে পারেন ... আপনার যদি ভৌগলিক এবং স্থানিক ডেটা সংরক্ষণ করতে হয় তবে আপনি এই উদ্দেশ্যে পোস্টগ্রিস ডাটাবেস ব্যবহার করতে পারেন। মাইএসকিউএল স্পেশিয়াল এক্সটেনশনগুলি একটি ভাল বিকল্প কারণ তারা ওপেনজিআইএস জ্যামিতি মডেলকে অনুসরণ করে। আমি সেগুলি ব্যবহার করিনি কারণ আমার আমার ডাটাবেস পোর্টেবল রাখার প্রয়োজন ছিল। postgis.net
gilcierweb

ডুড এটি কেবল একটি উদাহরণ, আপনি চান নির্ভুলতাটি ব্যবহার করতে পারেন, যদি দশমিক আপনাকে পোস্ট করতে না সহায়তা করে কেবল ভৌগলিক ও স্থানিক ডেটার জন্য তৈরি একটি ডাটাবেস ব্যবহার করে
গিলসিয়ার ওয়েব 3:58

-1

কোড ব্যবহার করতে / এর স্পষ্টতা প্রমাণ Oğuzhan KURNUÇ এর উত্তর

সংক্ষিপ্তসার:
অল্প আকারে (4 বি) গ্রেট স্পষ্টতা (cm 1 সেমি)।

পরিসীমা [-180, 180] এর মানের জন্য যথাক্রমে 7 দশমিক অঙ্ক very
এটি +1 -180 এর নিকটবর্তী 9 টি (বা "10 ডিজিটের প্রাথমিক সংখ্যা" যদি "180" এর প্রাথমিক "1" গণনা করা হয় ) জন্য 9 দশমিক ( 9 মিমি সেন্টিমিটার) থেকে ডানদিকে 7 ডিজিট
এটি একটি 4-বাইট ফ্লোটের সাথে বৈসাদৃশ্য করুন , যার মোট মাত্র digit 7 ডিজিট রয়েছে, সুতরাং + = 180 (m 1 মি) এর নিকটে দশমিকের ডানদিকে ~ 5 ডিজিট ।

এই পদ্ধতির ব্যবহারের পদ্ধতি:

const double Fixed7Mult = 10000000;

public static int DecimalDegreesToFixed7(double degrees)
{
    return RoundToInt(degrees * Fixed7Mult);
}

public static double Fixed7ToDecimalDegrees(int fixed7)
{
    return fixed7 / (double)Fixed7Mult;
}

নির্ভুলতার পরীক্ষা:

/// <summary>
/// This test barely fails in 7th digit to right of decimal point (0.0000001 as delta).
/// Passes with 0.0000002 as delta.
/// </summary>
internal static void TEST2A_LatLongPrecision()
{
    //VERY_SLOW_TEST Test2A_ForRange(-180, 360, 0.0000001);
    //FAILS Test2A_ForRange(-180, 0.1, 0.0000001);

    Test2A_ForRange(-180, 0.1, 0.0000002);
    Test2A_ForRange(0, 0.1, 0.0000002);
    Test2A_ForRange(179.9, 0.1, 0.0000002);
}

/// <summary>
/// Test for the smallest difference.  A: 9.9999994E-08.
/// </summary>
internal static void TEST2B_LatLongPrecision()
{
    double minDelta = double.MaxValue;
    double vAtMinDelta = 0;
    //VERY_SLOW_TEST Test2B_ForRange(-180, 360, ref minDelta, ref vAtMinDelta);
    Test2B_ForRange(-180, 0.1, ref minDelta, ref vAtMinDelta);
    Test2B_ForRange(0, 0.1, ref minDelta, ref vAtMinDelta);
    Test2B_ForRange(179.9, 0.1, ref minDelta, ref vAtMinDelta);

    // Fails. Smallest delta is 9.9999994E-08; due to slight rounding error in 7th decimal digit.
    //if (minDelta < 0.0000001)
    //  throw new InvalidProgramException($"Fixed7 has less than 7 decimal digits near {vAtMinDelta}");

    // Passes.
    if (minDelta < 0.000000099)
        throw new InvalidProgramException($"Fixed7 has less than 7 decimal digits near {vAtMinDelta}");
}

পরীক্ষার দ্বারা ব্যবহৃত সহায়ক পদ্ধতি:

private static void Test2A_ForRange(double minV, double range, double deltaV)
{
    double prevV = 0;
    int prevFixed7 = 0;
    bool firstTime = true;
    double maxV = minV + range;
    for (double v = minV; v <= maxV; v += deltaV) {
        int fixed7 = DecimalDegreesToFixed7(v);
        if (firstTime)
            firstTime = false;
        else {
            // Check for failure to distinguish two values that differ only in 7th decimal digit.
            // Fails.
            if (fixed7 == prevFixed7)
                throw new InvalidProgramException($"Fixed7 doesn't distinguish between {prevV} and {v}");
        }
        prevV = v;
        prevFixed7 = fixed7;
    }
}

private static void Test2B_ForRange(double minV, double range, ref double minDelta, ref double vAtMinDelta)
{
    int minFixed7 = DecimalDegreesToFixed7(minV);
    int maxFixed7 = DecimalDegreesToFixed7(minV + range);

    bool firstTime = true;
    double prevV = 0;   // Initial value is ignored.
    for (int fixed7 = minFixed7; fixed7 < maxFixed7; fixed7++) {
        double v = Fixed7ToDecimalDegrees(fixed7);
        if (firstTime)
            firstTime = false;
        else {
            double delta = Math.Abs(v - prevV);
            if (delta < minDelta) {
                minDelta = delta;
                vAtMinDelta = v;
            }
        }
        prevV = v;
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.