paint-brush
Vị trí, vị trí, vị trí! PostGIS và Heroku Postgrestừ tác giả@josephcaudle
681 lượt đọc
681 lượt đọc

Vị trí, vị trí, vị trí! PostGIS và Heroku Postgres

từ tác giả Joseph Caudle9m2024/04/16
Read on Terminal Reader

dài quá đọc không nổi

Gần đây, tôi được biết Heroku cũng hỗ trợ PostGIS. Cá nhân tôi chưa bao giờ sử dụng PostGIS trước đây. Tôi biết một số đối thủ cạnh tranh độc quyền đối với sản phẩm này, vì vậy tôi nghĩ đây sẽ là thời điểm tuyệt vời để thử tùy chọn nguồn mở.
featured image - Vị trí, vị trí, vị trí! PostGIS và Heroku Postgres
Joseph Caudle HackerNoon profile picture

Mở rộng Postgres để hỗ trợ truy vấn dữ liệu không gian địa lý

Tôi đã mất quá nhiều thời gian loay hoay với các cấu hình và dịch vụ chỉ để tạo ra một phiên bản điện toán trong AWS. Đôi khi, tôi chỉ cần một môi trường sẵn sàng cho sản xuất để thử nghiệm các ứng dụng và ý tưởng. Với Heroku, tôi có thể làm được điều đó chỉ bằng một vài lệnh đơn giản tại CLI.


Gần đây, tôi được biết Heroku cũnghỗ trợ PostGIS . Cá nhân tôi chưa bao giờ sử dụng PostGIS trước đây. Tôi biết một số đối thủ cạnh tranh độc quyền đối với sản phẩm này, vì vậy tôi nghĩ đây sẽ là thời điểm tuyệt vời để thử tùy chọn nguồn mở.


Trong bài viết này, tôi sẽ chỉ cho bạn cách để một phiên bản Postgres hỗ trợ PostGIS chạy trên Heroku. Sau đó, tôi sẽ chạy một số truy vấn mẫu trên cơ sở dữ liệu để giúp bạn hiểu cách thức hoạt động của nó. Và phần tốt nhất? Bạn có thể theo dõi và tự mình khám phá khi chúng tôi thực hiện!

PostGIS là gì?

Ngay cả khi bạn đã sử dụng Postgres một thời gian, bạn có thể chưa quen với PostGIS. GIS là viết tắt của Hệ thống thông tin địa lý . Có rất nhiều giải pháp trong không gian. Nhưng điều khiến PostGIS trở nên thú vị là nó dựa trên cơ sở dữ liệu PostgreSQL được nhiều người yêu thích. Ngoài tất cả hiệu suất mà bạn mong đợi từ Postgres, chúng tôi còn có một công cụ đầy đủ tính năng để lưu trữ dữ liệu không gian địa lý.


PostGIS không chỉ cung cấp giải pháp lưu trữ tốt cho loại dữ liệu này mà còn có thể được tích hợp liền mạch với một số ứng dụng có thể sử dụng dữ liệu này (chẳng hạn như ArcGIS và Tableau).


TL; DR—Nếu bạn cần xử lý, lưu trữ hoặc truy vấn dữ liệu vị trí, PostGIS là một lựa chọn tuyệt vời để thực hiện việc đó. May mắn thay, việc này chỉ đơn giản như việc thêm một tiện ích bổ sung vào ứng dụng Heroku để thiết lập và chạy một phiên bản Postgres mới. Vì vậy, hãy làm điều đó ngay bây giờ.

Chúng ta có thể sử dụng PostGIS như thế nào?

Để bắt đầu, bạn sẽ cần một ứng dụng có kích thước bất kỳ. Sau đó, bạn thêm một phiên bản Heroku Postgres vào ứng dụng của mình.

Tạo ứng dụng Heroku

Đối với bản demo của tôi, tôi sẽ tạo một ứng dụng trống.

Đính kèm tiện ích bổ sung Heroku Postgres

Sau khi ứng dụng được tạo, tôi có thể tạo tiện ích bổ sung Heroku Postgres. Vì tập dữ liệu mẫu của tôi quá lớn đối với phiên bản gói Mini nên tôi cần sử dụng gói Cơ bản để thay thế. Tôi có thể làm điều này từ dòng lệnh:

 $ heroku login $ heroku addons:create heroku-postgresql:basic -a postgis-demo Creating heroku-postgresql:basic on ⬢ postgis-demo... ~$0.013/hour (max $9/month) Database has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pg:copy Created postgresql-fitted-78461 as DATABASE_URL

Khi đã tạo xong cơ sở dữ liệu Postgres, tôi chỉ còn một vài bước nữađể thiết lập PostGIS .

Tạo tiện ích mở rộng PostGIS

Heroku Postgres có nhiều tiện ích mở rộng mà chúng tôi có thể cài đặt. Để liệt kê chúng, chúng ta có thể hỏi instance của mình:

 $ heroku pg:psql -a postgis-demo --> Connecting to postgresql-fitted-78461 … postgis-demo::DATABASE=> \x on; Expanded display is on. postgis-demo::DATABASE=> show extwlist.extensions; … address_standardizer,address_standardizer_data_us,amcheck,autoinc,bloom,btree_gin,btree_gist,citext,cube,dict_int,earthdistance,fuzzystrmatch,hstore,insert_username,intarray,isn,lo,ltree,moddatetime,pg_partman,pg_stat_statements,pg_trgm,pgcrypto,pgrowlocks,postgis,postgis_raster,postgis_topology,refint,seg,sslinfo,tablefunc,tcn,tsm_system_rows,tsm_system_time,unaccent,uuid-ossp


Chúng tôi thấy postgis trong danh sách các tiện ích mở rộng có sẵn. Từ đó, chúng ta có thể tạo tiện ích mở rộng.

 postgis-demo::DATABASE=> CREATE EXTENSION postgis; CREATE EXTENSION


Chúng tôi có thể xác nhận tiện ích mở rộng đã được cài đặt và kiểm tra phiên bản:

 postgis-demo::DATABASE=> SELECT postgis_version(); -[ RECORD 1 ]---+-------------------------------------- postgis_version | 3.4 USE_GEOS=1 USE_PROJ=1 USE_STATS=1


Được rồi! Có vẻ như chúng tôi đã sẵn sàng và chạy PostGIS 3.4.

Tải tập dữ liệu ban đầu

Bây giờ tôi đã bật tiện ích mở rộng PostGIS, tôi cần tải tập dữ liệu vào để thử nghiệm. Tôi đang sử dụng tập dữ liệu được cung cấp bởi sách Giới thiệu về PostGIS . Gói dữ liệu đã tải xuống là tệp zip 21,5 MB. Trong thư mục con data của kho lưu trữ được giải nén, có một tệp 9,5 MB có tên nyc_data.backup .


Đây là tệp chứa tất cả dữ liệu điều tra dân số từ cuộc điều tra dân số năm 2000 của Thành phố New York, cùng với tất cả các đường phố, khu dân cư và ga tàu điện ngầm trong thành phố.


Chúng ta có thể khôi phục bản sao lưu dữ liệu trực tiếp vào phiên bản Heroku Postgres bằng cách sử dụng lệnh heroku heroku pg:backups:restore . Điều này cực kỳ tiện lợi. Tuy nhiên, hãy ghi nhớ những lưu ý sau:


  • Không thể tải lên tệp sao lưu mà bạn có thể khôi phục từ máy cục bộ của mình. Nó phải có sẵn trực tuyến. May mắn thay, tôi đã tìm thấy một kho lưu trữ GitHub cung cấp nyc_data.backup .


  • Việc thực hiện khôi phục cơ sở dữ liệu bắt đầu bằng cách đặt lại hoàn toàn phiên bản Heroku Postgres của bạn, bao gồm cả việc cài đặt tiện ích mở rộng postgis . Vì vậy, mặc dù chúng tôi đã trình bày ở trên cách cài đặt tiện ích mở rộng theo cách thủ công, chúng tôi sẽ cần thêm cờ khi khôi phục cơ sở dữ liệu của mình để cài đặt sẵn tiện ích mở rộng trước khi tải dữ liệu.


Đây là lệnh chúng tôi sẽ sử dụng để khôi phục bản sao lưu cơ sở dữ liệu:

 $ heroku pg:backups:restore \ https://github.com/Giorgi/PostgresSamples/raw/main/nyc_data.backup \ -e postgis \ -a postgis-demo

Tệp sao lưu của chúng tôi được chỉ định thông qua một URL có thể truy cập công khai. Bạn luôn có thể tải xuống tập dữ liệu từ hướng dẫn PostGIS, giải nén tệp nyc_data.backup và đăng trực tuyến lên vị trí bạn chọn.


Cờ -e postgis chỉ định rằng chúng tôi muốn cài đặt tiện ích mở rộng postgis trước khi tải lược đồ và dữ liệu của bản sao lưu.


Điều đó là vậy đó! Không tệ đối với một vài lệnh đơn giản. Chúng tôi có cơ sở dữ liệu và dữ liệu của chúng tôi.

Tại sao lại là Heroku?

Nếu bạn đã biết cách thiết lập Postgres trên máy cục bộ, bạn có thể thắc mắc tại sao tôi lại chọn Heroku. Đối với tôi, lý do lớn nhất là sự đơn giản. Ngoài việc chọn gói Heroku Postgres đủ lớn cho phân tích mà tôi dự định thực hiện và cài đặt tiện ích mở rộng PostGIS, tôi không cần phải làm gì khác để thiết lập và chạy.


Ngoài ra, việc cộng tác trên bất kỳ phân tích nào tôi thực hiện thật dễ dàng. Tôi có thể cấp cho người khác quyền truy cập vào cơ sở dữ liệu của mình với tư cách cộng tác viên hoặc tôi có thể nhanh chóng xây dựng một ứng dụng trên cơ sở dữ liệu và chia sẻ quyền truy cập thông qua giao diện web thông thường, thay vì ứng dụng khách Postgres.


Cuối cùng, khi tôi hoàn thành một dự án và không cần nó nữa, tôi chỉ cần xóa ứng dụng trên Heroku là mọi thứ sẽ biến mất. Không có tập tin dữ liệu trên máy tính của tôi phải lo lắng. Không có phần mềm bổ sung được cài đặt cục bộ. Tôi có thể tận hưởng chuyến tham quan nhanh chóng vào công nghệ mới và sau đó tiếp tục khi hoàn thành.

Làm việc với PostGIS

Bây giờ, chúng ta hãy xem PostGIS hoạt động như thế nào.

Làm việc như bạn muốn với Postgres

Điều đầu tiên cần nhớ là PostGIS là một phần mở rộng trong Postgres. Điều đó có nghĩa là bạn cũng có thể thực hiện bất kỳ truy vấn Postgres tiêu chuẩn nào.


Giả sử tôi muốn tìm hiểu xem có bao nhiêu con phố ở New York bắt đầu bằng B. Một truy vấn SQL đơn giản sẽ cho tôi biết:

 postgis-demo::DATABASE=> SELECT count(*) postgis-demo::DATABASE-> FROM nyc_streets postgis-demo::DATABASE-> WHERE name LIKE 'B%'; count 1282 (1 row)


Số lượng khu dân cư ở mỗi quận như thế nào? Một lần nữa, một truy vấn SQL đơn giản:

 postgis-demo::DATABASE=> SELECT boroname, count(*) postgis-demo::DATABASE-> FROM nyc_neighborhoods postgis-demo::DATABASE-> GROUP BY boroname; boroname | count ---------------+------- Queens | 30 Brooklyn | 23 Staten Island | 24 The Bronx | 24 Manhattan | 28 (5 rows)

Cho đến nay, chúng ta mới thực hiện được PostgreSQL tiêu chuẩn. Bây giờ, chúng ta hãy xem cách sử dụng các tính năng của PostGIS.

Ví dụ về làm việc với hình học không gian địa lý

Bởi vì tập dữ liệu của chúng tôi bao gồm tất cả các đường phố ở New York, chúng tôi có thể hỏi có bao nhiêu km đường phố trong thành phố với truy vấn này:

 postgis-demo::DATABASE=> SELECT Sum(ST_Length(geom)) / 1000 as street_length FROM nyc_streets; street_length -------------------- 10418.904717199996 (1 row)


Chúng ta cũng có thể tính diện tích, chẳng hạn như diện tích của toàn bộ Manhattan:

 postgis-demo::DATABASE=> SELECT Sum(ST_Area(geom)) / 4047 as acreage FROM nyc_neighborhoods WHERE boroname = 'Manhattan'; acreage ------------------- 13965.32012239119 (1 row)

Lưu ý rằng những tính toán này đến từ dữ liệu không gian địa lý, không phải từ các cột liên quan đến dữ liệu tổng hợp thuộc loại này. Không chỉ vậy, những truy vấn này còn thực hiện cực kỳ nhanh chóng.


Một truy vấn cuối cùng mà tôi thực sự ngạc nhiên liên quan đến việc sử dụng các phép nối không gian . Giống như các phép nối cơ sở dữ liệu tiêu chuẩn, các phép nối không gian có thể hợp nhất nhiều bảng, nhưng trên cơ sở các mối quan hệ không gian. Ví dụ: chúng ta có thể truy vấn xem một ga tàu điện ngầm cụ thể nằm ở vùng lân cận nào bằng cách sử dụng dữ liệu không gian. Để làm điều này, chúng ta có thể sử dụng ST_Contains từ PostGIS để xác định xem hình học của vùng lân cận có chứa hoàn toàn hình học của ga tàu điện ngầm hay không.


Dựa vào tên của tàu điện ngầm (trong nyc_subway_stations ), chúng tôi truy vấn vùng lân cận (trong nyc_neighborhoods ) mà ST_Contains là đúng. Truy vấn của chúng tôi trông như thế này:

 postgis-demo::DATABASE=> SELECT subways.name AS subway_name, neighborhoods.name AS neighborhood_name, neighborhoods.boroname AS borough FROM nyc_neighborhoods AS neighborhoods JOIN nyc_subway_stations AS subways ON ST_Contains(neighborhoods.geom, subways.geom) WHERE subways.name = 'Broad St'; subway_name | neighborhood_name | borough -------------+--------------------+----------- Broad St | Financial District | Manhattan (1 row)

PostGIS thậm chí còn cung cấp chức năng truy vấn vị trí nâng cao hơn với hình học , nhưng điều đó nằm ngoài phạm vi bản demo đơn giản của chúng tôi tại đây.

Phần kết luận

Chưa bao giờ sử dụng PostGIS trước đây, tôi thực sự ấn tượng với những gì nó có thể làm được. Tôi còn có thể làm được nhiều điều hơn nữa với cơ sở dữ liệu này, vì tôi mới chỉ đọc được nửa chừng cuốn sách Giới thiệu chính thức về PostGIS . Không chỉ vậy, tôi có thể xây dựng và triển khai các ứng dụng trên PostGIS bằng cách sử dụng bất kỳ ngôn ngữ nào được Heroku hỗ trợ .


Cụ thể, tôi nghĩ rằng tôi có thể muốn tìm một trường hợp sử dụng để xây dựng ứng dụng Rails trên PostGIS. Tôi đã tìm thấy một số tài liệu về cách tôi có thể bắt đầu.


Nhưng hiện tại, tôi không cần phiên bản này nữa nên tôi sẽ dọn dẹp và xóa ứng dụng của mình. Từ CLI, đây là điều tôi cần làm:

 $ heroku apps:destroy postgis-demo ▸ WARNING: This will delete ⬢ postgis-demo including all add-ons. ▸ To proceed, type postgis-demo or re-run this command with --confirm postgis-demo > postgis-demo Destroying ⬢ postgis-demo (including all add-ons)... done

Đợi đã, chỉ vậy thôi à? Ừ, thế thôi. Chỉ với một lệnh và xác nhận, mọi thứ sẽ được giải quyết và tôi không cần phải lo lắng về điều đó nữa.

 $ heroku apps You have no apps. $ heroku addons No add-ons.

Bây giờ tôi đã xóa ứng dụng của mình, bạn có một cơ hội tuyệt vời: Tên ứng dụng duy nhất postgis-demo có sẵn cho độc giả đầu tiên muốn lấy nó trên Heroku! Bạn đã sẵn sàng xây dựng ứng dụng PostGIS tuyệt vời tiếp theo của mình chưa? Hôm nay là ngày!