2009-07-28 39 views
227

Khi lưu trữ dữ liệu vĩ độ hoặc kinh độ trong cơ sở dữ liệu tuân thủ ANSI SQL, kiểu dữ liệu nào thích hợp nhất? Nên sử dụng float hoặc decimal hoặc ...?Loại dữ liệu nào để sử dụng khi lưu trữ dữ liệu vĩ độ và kinh độ trong cơ sở dữ liệu SQL?

Tôi biết rằng Oracle, MySql và SQL Server đã thêm một số kiểu dữ liệu đặc biệt để xử lý dữ liệu địa lý, nhưng tôi quan tâm đến cách bạn lưu trữ thông tin trong cơ sở dữ liệu SQL "trơn tru".

+18

Câu hỏi trùng lặp này như thế nào? Ông rõ ràng yêu cầu cơ sở dữ liệu SQL vanilla trơn tru khi câu hỏi khác (và câu trả lời có quá) thảo luận về MySQL cụ thể. – Atul

+4

Atul là đúng, nó không phải là cùng một câu hỏi cũng bởi vì một trong những khác xác định rằng các phép tính sẽ được thực hiện trên lat/lng. Tôi chỉ nhận ra rằng câu trả lời của tôi từ câu trả lời khác là phù hợp nhất ở đây, vì vậy hãy xem: http://stackoverflow.com/a/25120203/1226018 – Simon

+0

Tôi sẽ kêu vang trong, năm sau đó. Atul và Simon đúng. Đây là những câu hỏi khác nhau về chức năng. Đánh dấu điều này là trùng lặp có thể tương đương với việc nói rằng yêu cầu làm thế nào để duy trì một bản ghi trong cơ sở dữ liệu bằng C# và Python là các bản sao. –

Trả lời

331

Decimal(9,6)

Nếu bạn không sử dụng các thông số chính xác và quy mô, đây là một chuỗi định dạng hình ảnh:

###.######

+19

+1: Tránh kỳ quặc lỗi vòng tròn bằng cách sử dụng số chữ số thập phân cố định. –

+9

Vì mục đích của chúng, Wikipedia đề xuất: "Tránh độ chính xác quá mức (0,0001 ° <11 m, 1 ′ ′ <31 m)". http://en.wikipedia.org/wiki/Wikipedia:Obtaining_geographic_coordinates Để làm cho trường của tôi thêm chính xác, tôi cũng đã quyết định sử dụng sáu chữ số bên phải dấu thập phân và ba chữ số ở bên trái. Tôi vui vì câu trả lời này xác nhận đó là một quyết định tốt. –

+1

Kiểm tra câu trả lời cuối cùng nhưng một trong bài viết này [http://groups.google.com/group/google-maps-api/browse_thread/thread/b928b5fbc5351821). Người sử dụng William giải thích rất tốt những gì xảy ra với độ chính xác trong khi bạn nhận được đến nay từ đường xích đạo. – Throoze

5

Chúng tôi sử dụng float, nhưng bất kỳ hương vị của số với 6 chữ số thập phân nên cũng làm việc.

+27

Một phép tính có thể giới thiệu các chữ số phụ chỉ là tiếng ồn. Ngoài ra chuyển đổi thập phân sang nhị phân sẽ làm cho vị trí thập phân cuối cùng đáng ngờ và có thể sai. Phạt tiền cho một số mục đích. Lousy để điều hướng. –

+4

S> Lott, tôi muốn bình luận của bạn một triệu lần nếu tôi có thể, không bao giờ sử dụng phao cho lat và dài. – HLGEM

+1

Tôi không nghĩ rằng phao đề xuất xứng đáng được giảm tốc - bạn đã cho tôi đoán trước và tìm kiếm ở đâu đó để có câu trả lời: http://stackoverflow.com/questions/551894/whats-the-best-way-to-store -co-ordinates-longitude-latitude-from-google-maps – Keith

1

Tôi sẽ sử dụng số thập phân có độ chính xác phù hợp cho dữ liệu của bạn.

1

Tôi nghĩ rằng nó phụ thuộc vào các hoạt động bạn sẽ cần phải làm thường xuyên nhất.

Nếu bạn cần giá trị đầy đủ dưới dạng số thập phân, hãy sử dụng số thập phân với độ chính xác và tỷ lệ phù hợp. Float là cách vượt ra ngoài nhu cầu của bạn, tôi tin.

Nếu bạn sẽ được chuyển đến/từ "ký hiệu phần degºmin'sec thường, tôi muốn xem xét lưu trữ mỗi giá trị như một loại nguyên (smallint, tinyint, tinyint, smallint?).

1

Vâng, bạn hỏi làm thế nào để lưu trữ Latitude/kinh độ và câu trả lời của tôi là: Đừng, bạn có thể xem xét việc sử dụng WGS 84 (ở châu Âu ETRS 89) vì nó là tiêu chuẩn cho các tham chiếu Geo. trong những ngày trước khi SQL 2008 cuối cùng bao gồm hỗ trợ địa lý

2

Trong vanilla Oracle, tính năng ca LOCATOR lled (một phiên bản tê liệt của không gian) yêu cầu dữ liệu tọa độ được lưu trữ bằng cách sử dụng kiểu dữ liệu của NUMBER (không có độ chính xác). Khi bạn cố gắng tạo các chỉ mục dựa trên chức năng để hỗ trợ các truy vấn không gian, nó sẽ gag khác.

2

Bạn có thể dễ dàng lưu trữ một lat/lon số thập phân trong một trường unsigned integer, thay vì tách chúng trong một số nguyên và phần thập phân và lưu trữ những riêng biệt như phần nào gợi ý ở đây sử dụng các thuật toán chuyển đổi sau:

như một hàm mysql lưu trữ:

CREATE DEFINER=`r`@`l` FUNCTION `PositionSmallToFloat`(s INT) 
RETURNS decimal(10,7) 
DETERMINISTIC 
RETURN if(((s > 0) && (s >> 31)) , (-(0x7FFFFFFF - 
(s & 0x7FFFFFFF)))/600000, s/600000) 

và lưng

CREATE DEFINER=`r`@`l` FUNCTION `PositionFloatToSmall`(s DECIMAL(10,7)) 
RETURNS int(10) 
DETERMINISTIC 
RETURN s * 600000 

Điều đó cần phải được lưu trữ trong một int unsigned (10), công trình này trong mysql cũng như trong sqlite đó là typeless.

thông qua trải nghiệm, tôi thấy rằng công cụ này hoạt động rất nhanh, nếu tất cả những gì bạn cần là lưu trữ tọa độ và truy xuất các tọa độ đó để thực hiện một số phép toán.

trong php những 2 chức năng giống như

function LatitudeSmallToFloat($LatitudeSmall){ 
    if(($LatitudeSmall>0)&&($LatitudeSmall>>31)) 
    $LatitudeSmall=-(0x7FFFFFFF-($LatitudeSmall&0x7FFFFFFF))-1; 
    return (float)$LatitudeSmall/(float)600000; 
} 

và ngược lại:

function LatitudeFloatToSmall($LatitudeFloat){ 
    $Latitude=round((float)$LatitudeFloat*(float)600000); 
    if($Latitude<0) $Latitude+=0xFFFFFFFF; 
    return $Latitude; 
} 

này được một số lợi thế bổ sung cũng trong nhiệm kỳ của việc tạo ra ví dụ phím độc đáo memcached với số nguyên. (ví dụ: để cache kết quả mã địa lý). Hy vọng điều này sẽ làm tăng thêm giá trị cho cuộc thảo luận.

ứng dụng khác có thể là khi bạn đang không có phần mở rộng GIS và chỉ đơn giản là muốn giữ lại một vài triệu của những cặp lat/lon, bạn có thể sử dụng các phân vùng trên các lĩnh vực này trong mysql được hưởng lợi từ thực tế, họ là các số nguyên:

Create Table: CREATE TABLE `Locations` (
    `lat` int(10) unsigned NOT NULL, 
    `lon` int(10) unsigned NOT NULL, 
    `location` text, 
    PRIMARY KEY (`lat`,`lon`) USING BTREE, 
    KEY `index_location` (`locationText`(30)) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 
/*!50100 PARTITION BY KEY() 
PARTITIONS 100 */ 
Các vấn đề liên quan