ما هو نوع البيانات المثالي الذي يجب استخدامه عند تخزين خطوط الطول والعرض في قاعدة بيانات MySQL؟

StackOverflow https://stackoverflow.com/questions/159255

سؤال

مع الأخذ في الاعتبار أنني سأقوم بإجراء العمليات الحسابية على أزواج خطوط العرض/الطويلة، ما نوع البيانات الأنسب للاستخدام مع قاعدة بيانات MySQL؟

هل كانت مفيدة؟

المحلول

استخدم ملحقات المكانية مع نظم المعلومات الجغرافية.

نصائح أخرى

ويوفر جوجل البداية الى النهاية PHP / ماي حل للحصول على مثال "فروعنا" التطبيق مع خرائط جوجل. في هذا المثال، وتخزين الغاز الطبيعي المسال القيم / اللات باسم "تعويم" الذي يبلغ طوله "10،6"

http://code.google.com/apis/maps/articles/ phpsqlsearch.html

وأساسا أنها تعتمد على الدقة تحتاج لمواقعك. استخدام مزدوج سيكون لديك الدقة 3.5nm. العشرى (8،6) / (9،6) وتنخفض إلى 16CM. تعويم هو 1.7M ...

وهذا الجدول مثيرة جدا للاهتمام لديه قائمة أكثر اكتمالا: http://mysql.rjweb.org/ doc.php / خط الطول والعرض :

Datatype               Bytes            Resolution

Deg*100 (SMALLINT)     4      1570 m    1.0 mi  Cities
DECIMAL(4,2)/(5,2)     5      1570 m    1.0 mi  Cities
SMALLINT scaled        4       682 m    0.4 mi  Cities
Deg*10000 (MEDIUMINT)  6        16 m     52 ft  Houses/Businesses
DECIMAL(6,4)/(7,4)     7        16 m     52 ft  Houses/Businesses
MEDIUMINT scaled       6       2.7 m    8.8 ft
FLOAT                  8       1.7 m    5.6 ft
DECIMAL(8,6)/(9,6)     9        16cm    1/2 ft  Friends in a mall
Deg*10000000 (INT)     8        16mm    5/8 in  Marbles
DOUBLE                16       3.5nm     ...    Fleas on a dog

وآمل أن يساعد هذا.

والامتدادات المكانية الخلية هي الخيار الأفضل لأن لديك قائمة كاملة من مشغلي المكانية ومؤشرات تحت تصرفكم. وهناك مؤشر المكاني يسمح لك لإجراء عمليات حسابية على أساس المسافة بسرعة كبيرة. يرجى أن نضع في اعتبارنا أنه اعتبارا من 6.0، وتمديد المكانية لا تزال غير مكتملة. أنا لا اخماد الخلية المكاني، والسماح فقط تعرف من المزالق قبل أن تحصل بعيدا جدا جنبا إلى جنب في هذا الشأن.

إذا كنت تتعامل بصرامة مع نقطة وفقط وظيفة عن بعد، وهذا على ما يرام. إذا كنت بحاجة إلى أن تفعل أي حسابات مع المضلعات، خطوط، أو مخزنة-نقاط، ومشغلي المكانية لا توفر نتائج دقيقة إلا إذا كنت تستخدم مشغل "ربط". انظر التحذير في الجزء العلوي من <لأ href = "http://dev.mysql.com/doc/refman/6.0/en/functions-that-test-spatial-relationships-between-geometries.html" يختلط = "noreferrer "> 21.5.6 . العلاقات مثل تحتوي، ضمن، أو يتقاطع يستخدمون MBR، وليس الشكل الهندسي الدقيق (أي يتم التعامل على البيضوي مثل مستطيل).

وكذلك المسافات في الخلية المكانية هي في نفس وحدات الهندسة الأولى. وهذا يعني إذا كنت تستخدم الدرجات العشرية، ثم قياسات المسافة الخاصة بك في الدرجات العشرية. وهذا سيجعل من الصعب جدا الحصول على نتائج دقيقة كما يمكنك الحصول فورثور من خط الاستواء.

وعندما فعلت ذلك لقاعدة بيانات الملاحة المدمج من ARINC424 لم لا بأس به من اختبار وإذا نظرنا إلى الوراء في رمز، أنا استخدم العشرى (18،12) (في الواقع رقمية (18،12) لأنه كان فيربيرد ).

والعربات والزوجي ليست دقيقة كما ويمكن أن يؤدي إلى أخطاء التقريب التي قد تكون أمرا سيئا للغاية. لا أستطيع أن أتذكر إذا وجدت أية بيانات الحقيقي الذي يعاني من مشاكل - ولكن أنا متأكد تماما أن عدم القدرة على تخزين بدقة في تعويم أو مزدوج يمكن أن يسبب مشاكل

وهذه النقطة هي أنه عند استخدام درجات أو راديان نعرف مجموعة من القيم - والجزء الكسري يحتاج معظم الأرقام

.

الخلية المكانية الامتدادات هي بديل جيد لأنها تتبع وOpenGIS الهندسة نموذج . لم أكن استخدامها لأنني في حاجة للحفاظ على قاعدة البيانات الخاصة بي المحمولة.

يعتمد على الدقة التي تحتاجها.

Datatype           Bytes       resolution
------------------ -----  --------------------------------
Deg*100 (SMALLINT)     4  1570 m    1.0 mi  Cities
DECIMAL(4,2)/(5,2)     5  1570 m    1.0 mi  Cities
SMALLINT scaled        4   682 m    0.4 mi  Cities
Deg*10000 (MEDIUMINT)  6    16 m     52 ft  Houses/Businesses
DECIMAL(6,4)/(7,4)     7    16 m     52 ft  Houses/Businesses
MEDIUMINT scaled       6   2.7 m    8.8 ft
FLOAT                  8   1.7 m    5.6 ft
DECIMAL(8,6)/(9,6)     9    16cm    1/2 ft  Friends in a mall
Deg*10000000 (INT)     8    16mm    5/8 in  Marbles
DOUBLE                16   3.5nm     ...    Fleas on a dog

من: http://mysql.rjweb.org/doc.php/latlng

لتلخيص:

  • الخيار الأكثر دقة المتاحة هو DOUBLE.
  • النوع الأكثر شيوعًا المستخدم هو DECIMAL(8,6)/(9,6).

اعتبارا من ماي إس كيو إل 5.7, ، فكر في استخدام أنواع البيانات المكانية (SDT) على وجه التحديد POINT لتخزين إحداثيات واحدة.قبل الإصدار 5.7، لم يكن SDT يدعم الفهارس (باستثناء الإصدار 5.6 عندما يكون نوع الجدول هو MyISAM).

ملحوظة:

  • عند الاستخدام POINT فئة، يجب أن يكون ترتيب الوسائط لتخزين الإحداثيات POINT(latitude, longitude).
  • هناك بناء جملة خاص ل إنشاء فهرس مكاني.
  • أكبر فائدة لاستخدام المعاملة الخاصة والتفضيلية (SDT) هي أنه يمكنك الوصول إليها وظائف التحليلات المكانية, ، على سبيل المثال.حساب المسافة بين نقطتين (ST_Distance) وتحديد ما إذا كانت هناك نقطة واحدة موجودة ضمن منطقة أخرى (ST_Contains).

وبناء على هذه المادة ويكي http://en.wikipedia.org/wiki/Decimal_degrees#Accuracy نوع البيانات المناسبة في الخلية هو عشري (9،6) لتخزين خطوط الطول والعرض في حقول منفصلة.

استخدم DECIMAL(8,6) لخط العرض (90 إلى -90 درجة) وDECIMAL(9,6) عن الطول (180 إلى -180 درجة). 6 منازل عشرية على ما يرام بالنسبة لمعظم التطبيقات. كلا يجب ان "توقيع" للسماح للقيم السالبة.

لا حاجة للذهاب بعيدا، وفقا لخرائط جوجل، والأفضل هو تعويم (10،6) للغاز الطبيعي المسال خطوط الطول و.

ونحن تخزين خط العرض / خط الطول X 1،000،000 في قاعدة بيانات أوراكل لدينا وأرقام لتجنب جولة إيقاف الأخطاء مع الزوجي.

ونظرا إلى أن خطوط العرض / الطول إلى المكان العشري 6TH كان 10 سم الدقة التي كان كل ما نحتاجه. العديد من قواعد البيانات الأخرى أيضا تخزين خطوط الطول / العرض إلى المكان العشري 6TH.

ومن منظور مختلف تمامًا وأبسط:

  • إذا كنت تعتمد على Google لعرض خرائطك، وعلاماتك، ومضلعاتك، أو أي شيء آخر، فاسمح لـ Google بإجراء الحسابات!
  • يمكنك حفظ الموارد على الخادم الخاص بك ويمكنك ببساطة تخزين خطوط الطول والعرض معًا كسلسلة واحدة (VARCHAR)، على سبيل المثال:"-0000.0000001,-0000.000000000000001"(طول 35 وإذا كان الرقم يحتوي على أكثر من 7 أرقام عشرية، فسيتم تقريبه)؛
  • إذا قامت Google بإرجاع أكثر من 7 أرقام عشرية لكل رقم، فيمكنك تخزين تلك البيانات في السلسلة الخاصة بك على أي حال، فقط في حالة رغبتك في اكتشاف بعض البيانات يهرب أو الميكروبات في المستقبل;
  • يمكنك استخدام بهم مصفوفة المسافة أو بهم مكتبة الهندسة لحساب المسافات أو كشف النقاط في مناطق معينة مع مكالمات بسيطة مثل هذا: google.maps.geometry.poly.containsLocation(latLng, bermudaTrianglePolygon))
  • هناك الكثير من واجهات برمجة التطبيقات "من جانب الخادم" التي يمكنك استخدامها (في بايثون, روبي على القضبان, بي أتش بي, CodeIgniter, لارافيل, يي, إطار زند, وما إلى ذلك) التي تستخدم واجهة برمجة تطبيقات خرائط Google.

بهذه الطريقة لا داعي للقلق بشأن فهرسة الأرقام وجميع المشكلات الأخرى المرتبطة بأنواع البيانات التي قد تفسد إحداثياتك.

وهذا يتوقف على لك التطبيق، أقترح استخدام تعويم (9،6)

سوف

ومفاتيح المكانية تعطيك المزيد من الميزات، ولكن في من معايير إنتاج العوامات وأسرع بكثير من مفاتيح المكانية. (0،01 VS 0001 في AVG)

والخلية يستخدم ضعفين عن كل يطفو ... وذلك باستخدام نوع مزدوجة. وسوف تستخدم تعويم يؤدي إلى القيم مدورة لا يمكن التنبؤ بها في معظم الحالات

على الرغم من أن هذا ليس الحل الأمثل لجميع العمليات، إلا أنه إذا كنت تقوم بإنشاء مربعات للخريطة أو تعمل باستخدام أعداد كبيرة من العلامات (النقاط) بإسقاط واحد فقط (على سبيل المثال.Mercator، مثل خرائط Google والعديد من أطر عمل الخرائط الزلقة الأخرى التي تتوقعها)، لقد وجدت ما أسميه "نظام الإحداثيات الواسع" مفيدًا حقًا.بشكل أساسي، تقوم بتخزين إحداثيات البكسل x وy بطريقة مكبرة - أستخدم مستوى التكبير 23.وهذا له فوائد عديدة:

  • يمكنك إجراء تحويل وحدات البكسل lat/lng الباهظة الثمن إلى مركاتور مرة واحدة بدلاً من كل مرة تتعامل فيها مع هذه النقطة
  • يتطلب الحصول على إحداثيات التجانب من سجل معين لمستوى التكبير/التصغير إزاحة واحدة لليمين.
  • يتطلب الحصول على إحداثيات البكسل من السجل إزاحة واحدة لليمين وإزاحة واحدة للبت AND.
  • تعتبر الإزاحات خفيفة الوزن للغاية بحيث يكون من العملي إجراؤها في SQL، مما يعني أنه يمكنك إجراء DISTINCT لإرجاع سجل واحد فقط لكل موقع بكسل، مما سيؤدي إلى تقليل عدد السجلات التي يتم إرجاعها بواسطة الواجهة الخلفية، مما يعني معالجة أقل على نهاية المقدمة.

لقد تحدثت عن كل هذا في تدوينة حديثة: http://blog.webfoot.com/2013/03/12/optimizing-map-tile-generation/

أنا مندهش للغاية من بعض الإجابات/التعليقات.

لماذا بحق السماء يكون أي شخص على استعداد "لتقليل الدقة مسبقًا" طوعًا، ثم بعد ذلك إجراء حسابات على الأرقام الأسوأ؟يبدو غبيا في نهاية المطاف.

إذا كان المصدر بدقة 64 بت، فمن المؤكد أنه سيكون من الغباء إصلاح المقياس طوعًا على سبيل المثال.6 أرقام عشرية، وحدد الدقة بحد أقصى 9 أرقام مهمة (وهو ما يحدث مع التنسيق العشري 9.6 المقترح بشكل شائع).

وبطبيعة الحال، يقوم المرء بتخزين البيانات بنفس الدقة التي تتمتع بها المادة المصدر.السبب الوحيد لتقليل الدقة هو مساحة التخزين المحدودة.

  • قم بتخزين أرقام المصدر بدقة أصلية
  • قم بتخزين الأرقام المحسوبة من المصدر بدقة إجراء الحساب (على سبيل المثال.إذا كان رمز التطبيق يستخدم مضاعفات، قم بتخزين النتائج كمضاعفات)

يؤدي التنسيق العشري 9.6 إلى ظاهرة التوصيل بالشبكة.وينبغي أن تكون هذه هي الخطوة الأخيرة، إذا كان لها أن تحدث على الإطلاق.

لن أدعو الأخطاء المتراكمة إلى عشي.

وظائف المكانية في PostGIS هي أكثر وظيفية كبيرة (أي لا قيود على عمليات BBOX) من تلك في وظائف المكانية الخلية. التحقق من ذلك: ربط النص

ليرة تركية؛ د

استخدم FLOAT(8,5) إذا كنت لا تعمل في NASA/الجيش ولا تصنع أنظمة الملاحة البحرية للطائرات.


للإجابة على سؤالك بشكل كامل، عليك أن تأخذ في الاعتبار عدة أشياء:

شكل

  • درجات دقائق ثواني:40° 26′ 46″ شمالاً 79° 58′ 56″ غربًا
  • درجات عشرية دقيقة:40° 26.767′ شمالاً 79° 58.933′ غربًا
  • الدرجات العشرية 1:40.446 درجة شمالاً 79.982 درجة غربًا
  • الدرجات العشرية 2: -32.60875, 21.27812
  • بعض التنسيقات الأخرى محلية الصنع؟لا أحد يمنعك من إنشاء نظام إحداثيات مركزي خاص بك وتخزينه كعنوان ومسافة من منزلك.قد يكون هذا منطقيًا بالنسبة لبعض المشكلات المحددة التي تعمل عليها.

لذا فإن الجزء الأول من الإجابة سيكون - يمكنك تخزين الإحداثيات في ملف تنسيق يستخدم التطبيق الخاص بك لتجنب التحويلات المستمرة ذهابًا وإيابًا وإجراء استعلامات SQL أبسط.

على الأرجح أنك تستخدم خرائط Google أو OSM لعرض بياناتك، وتستخدم GMaps تنسيق "الدرجات العشرية 2".لذلك سيكون من الأسهل تخزين الإحداثيات بنفس التنسيق.

دقة

بعد ذلك، تريد تحديد الدقة التي تحتاجها.بالطبع يمكنك تخزين الإحداثيات مثل "-32.608697550570334,21.278081997935146"، ولكن هل سبق لك أن اهتمت بالملليمتر أثناء التنقل إلى النقطة؟إذا كنت لا تعمل في ناسا ولا تقوم بمسارات الأقمار الصناعية أو الصواريخ أو الطائرات، فيجب أن تكون على ما يرام مع دقة عدة أمتار.

التنسيق الشائع الاستخدام هو 5 أرقام بعد النقاط مما يمنحك دقة تبلغ 50 سم.

مثال:هناك مسافة 1 سم بين X،21.2780818 والعاشر،21.2780819.لذا فإن 7 أرقام بعد النقطة تعطيك دقة 1/2 سم و5 أرقام بعد النقطة ستمنحك دقة 1/2 متر (لأن الحد الأدنى للمسافة بين النقاط المميزة هو 1 متر، لذلك لا يمكن أن يكون خطأ التقريب أكثر من نصفه).بالنسبة لمعظم الأغراض المدنية ينبغي أن يكون كافيا.

يمنحك تنسيق الدقائق العشرية بالدرجات (40° 26.767′ N 79° 58.933′ W) نفس الدقة تمامًا مثل 5 أرقام بعد النقطة

تخزين موفر للمساحة

إذا قمت بتحديد التنسيق العشري، فسيكون الإحداثي زوجًا (-32.60875، 21.27812).من الواضح أن 2 x (بت واحد للعلامة ورقمين للدرجات و5 أرقام للأس) سيكون كافيًا.

لذا هنا أود أن أدعم أليكس أكسل من التعليقات التي تقول إن اقتراح Google بتخزينه في FLOAT(10,6) يعد أمرًا إضافيًا حقًا، لأنك لا تحتاج إلى 4 أرقام للجزء الرئيسي (نظرًا لأن العلامة منفصلة وخط العرض محدود بـ 90 وخط الطول محدود بـ 180).يمكنك بسهولة استخدام FLOAT(8,5) لدقة 1/2 م أو FLOAT(9,6) لدقة 50/2 سم.أو يمكنك حتى تخزين خطوط الطول والعرض في أنواع منفصلة، ​​لأن FLOAT(7,5) يكفي لخطوط العرض.راجع أنواع تعويم MySQL مرجع.سيكون أي منها مثل FLOAT العادي ويساوي 4 بايت على أي حال.

عادةً لا تمثل المساحة مشكلة في الوقت الحاضر، ولكن إذا كنت تريد حقًا تحسين مساحة التخزين لسبب ما (إخلاء المسؤولية:لا تقم بالتحسين المسبق)، يمكنك ضغط خطوط العرض (لا تزيد عن 91000 قيمة + علامة) + طويلة (لا تزيد عن 181000 قيمة + علامة) إلى 21 بت وهو أقل بكثير من 2xFLOAT (8 بايت == 64 بت)

  1. تتراوح خطوط العرض من -90 إلى +90 (درجة)، لذا فإن DECIMAL(10, 8) مناسب لذلك

  2. تتراوح خطوط الطول من -180 إلى +180 (درجة) لذا تحتاج إلى DECIMAL(11, 8).

ملحوظة:الرقم الأول هو إجمالي عدد الأرقام المخزنة، والثاني هو الرقم بعد العلامة العشرية.

باختصار: lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL

تتطلب

وحسابات طويلة اللات الدقة، وذلك باستخدام نوع من نوع العشري وجعل الدقة 2 على الأقل أعلى من الرقم الذي سيتم تخزين من أجل إجراء عمليات حسابية الرياضيات. أنا لا أعرف عن بلدي أنواع البيانات SQL ولكن في الناس الخادم SQL غالبا ما تستخدم تعويم أو حقيقية بدلا من عشري والدخول في مأزق بسبب وتقدر أرقام حقيقية لا وهذه هي. لذلك فقط للتأكد من نوع البيانات التي تستخدمها هو نوع عشري صحيح وليس العائمة نوع عشري، ويجب أن يكون على ما يرام.

وA FLOAT يجب أن يوفر لك كل من الدقة التي تحتاج إليها، ويكون أفضل لوظائف المقارنة من تخزين كل تنسق كسلسلة أو ما شابه ذلك.

إذا الخلية إصدار أقدم من 5.0.3، قد تحتاج إلى يأخذوا حذرهم من بعض <لأ href = "http://dev.mysql.com/doc/refman/4.1/en/problems-with-float هتمل "يختلط =" نوفولو noreferrer "> العائمة أخطاء المقارنة نقطة لكن.

<اقتباس فقرة>   

وقبل الخلية 5.0.3، والأعمدة العشرية تخزين القيم مع دقة بدقة لأنها ممثلة كسلاسل، ولكن العمليات الحسابية على القيم العشرى وذلك باستخدام عمليات الفاصلة العائمة. اعتبارا من 5.0.3، الخلية تنفيذ العمليات العشرية مع دقة من 64 أرقام عشرية، والتي ينبغي أن حل مشاكل عدم دقة الأكثر شيوعا عندما يتعلق الأمر العشرية الأعمدة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top