]> git.openstreetmap.org Git - nominatim.git/blob - docs/develop/Database-Layout.md
work around strange query planning behaviour
[nominatim.git] / docs / develop / Database-Layout.md
1 # Database Layout
2
3 ### Import tables
4
5 OSM data is initially imported using [osm2pgsql](https://osm2pgsql.org).
6 Nominatim uses its own data output style 'gazetteer', which differs from the
7 output style created for map rendering.
8
9 The import process creates the following tables:
10
11 ![osm2pgsql tables](osm2pgsql-tables.svg)
12
13 The `planet_osm_*` tables are the usual backing tables for OSM data. Note
14 that Nominatim uses them to look up special relations and to find nodes on
15 ways.
16
17 The gazetteer style produces a single table `place` as output with the following
18 columns:
19
20  * `osm_type` - kind of OSM object (**N** - node, **W** - way, **R** - relation)
21  * `osm_id` - original OSM ID
22  * `class` - key of principal tag defining the object type
23  * `type` - value of principal tag defining the object type
24  * `name` - collection of tags that contain a name or reference
25  * `admin_level` - numerical value of the tagged administrative level
26  * `address` - collection of tags defining the address of an object
27  * `extratags` - collection of additional interesting tags that are not
28                  directly relevant for searching
29  * `geometry` - geometry of the object (in WGS84)
30
31 A single OSM object may appear multiple times in this table when it is tagged
32 with multiple tags that may constitute a principal tag. Take for example a
33 motorway bridge. In OSM, this would be a way which is tagged with
34 `highway=motorway` and `bridge=yes`. This way would appear in the `place` table
35 once with `class` of `highway` and once with a `class` of `bridge`. Thus the
36 *unique key* for `place` is (`osm_type`, `osm_id`, `class`).
37
38 How raw OSM tags are mapped to the columns in the place table is to a certain
39 degree configurable. See [Customizing Import Styles](../customize/Import-Styles.md)
40 for more information.
41
42 ### Search tables
43
44 The following tables carry all information needed to do the search:
45
46 ![search tables](search-tables.svg)
47
48 The **placex** table is the central table that saves all information about the
49 searchable places in Nominatim. The basic columns are the same as for the
50 place table and have the same meaning. The placex tables adds the following
51 additional columns:
52
53  * `place_id` - the internal unique ID to identify the place
54  * `partition` - the id to use with partitioned tables (see below)
55  * `geometry_sector` - a location hash used for geographically close ordering
56  * `parent_place_id` - the next higher place in the address hierarchy, only
57    relevant for POI-type places (with rank 30)
58  * `linked_place_id` - place ID of the place this object has been merged with.
59    When this ID is set, then the place is invisible for search.
60  * `importance` - measure how well known the place is
61  * `rank_search`, `rank_address` - search and address rank (see [Customizing ranking](../customize/Ranking.md)
62  * `wikipedia` - the wikipedia page used for computing the importance of the place
63  * `country_code` - the country the place is located in
64  * `housenumber` - normalized housenumber, if the place has one
65  * `postcode` - computed postcode for the place
66  * `indexed_status` - processing status of the place (0 - ready, 1 - freshly inserted, 2 - needs updating, 100 - needs deletion)
67  * `indexed_date` - timestamp when the place was processed last
68  * `centroid` - a point feature for the place
69
70 The **location_property_osmline** table is a special table for
71 [address interpolations](https://wiki.openstreetmap.org/wiki/Addresses#Using_interpolation).
72 The columns have the same meaning and use as the columns with the same name in
73 the placex table. Only three columns are special:
74
75  * `startnumber` and `endnumber` - beginning and end of the number range
76     for the interpolation
77  * `interpolationtype` - a string `odd`, `even` or `all` to indicate
78     the interval between the numbers
79
80 Address interpolations are always ways in OSM, which is why there is no column
81 `osm_type`.
82
83 The **location_postcode** table holds computed centroids of all postcodes that
84 can be found in the OSM data. The meaning of the columns is again the same
85 as that of the placex table.
86
87 Every place needs an address, a set of surrounding places that describe the
88 location of the place. The set of address places is made up of OSM places
89 themselves. The **place_addressline** table cross-references for each place
90 all the places that make up its address. Two columns define the address
91 relation:
92
93   * `place_id` - reference to the place being addressed
94   * `address_place_id` - reference to the place serving as an address part
95
96 The most of the columns cache information from the placex entry of the address
97 part. The exceptions are:
98
99   * `fromarea` - is true if the address part has an area geometry and can
100     therefore be considered preceise
101   * `isaddress` - is true if the address part should show up in the address
102     output. Sometimes there are multiple places competing for for same address
103     type (e.g. multiple cities) and this field resolves the tie.
104
105 The **search_name** table contains the search index proper. It saves for each
106 place the terms with which the place can be found. The terms are split into
107 the name itself and all terms that make up the address. The table mirrors some
108 of the columns from placex for faster lookup.
109
110 Search terms are not saved as strings. Each term is assigned an integer and those
111 integers are saved in the name and address vectors of the search_name table. The
112 **word** table serves as the lookup table from string to such a word ID. The
113 exact content of the word table depends on the [tokenizer](Tokenizers.md) used.
114
115 ## Address computation tables
116
117 Next to the main search tables, there is a set of secondary helper tables used
118 to compute the address relations between places. These tables are partitioned.
119 Each country is assigned a partition number in the country_name table (see
120 below) and the data is then split between a set of tables, one for each
121 partition. Note that Nominatim still manually manages partitioned tables.
122 Native support for partitions in PostgreSQL only became usable with version 13.
123 It will be a little while before Nominatim drops support for older versions.
124
125 ![address tables](address-tables.svg)
126
127 The **search_name_X** tables are used to look up streets that appear in the
128 `addr:street` tag.
129
130 The **location_area_large_X** tables are used to look up larger areas
131 (administrative boundaries and place nodes) either through their geographic
132 closeness or through `addr:*` entries.
133
134 The **location_road_X** tables are used to find the closest street for a
135 dependent place.
136
137 All three table cache specific information from the placex table for their
138 selected subset of places:
139
140  * `keywords` and `name_vector` contain lists of term ids (from the word table)
141    that the full name of the place should match against
142  * `isguess` is true for places that are not described by an area
143
144 All other columns reflect their counterpart in the placex table.
145
146 ## Static data tables
147
148 Nominatim also creates a number of static tables at import:
149
150  * `nominatim_properties` saves settings that must not be changed after
151     import
152  * `address_levels` save the rank information from the
153    [ranking configuration](../customize/Ranking.md)
154  * `country_name` contains a fallback of names for all countries, their
155    default languages and saves the assignment of countries to partitions.
156  * `country_osm_grid` provides a fallback for country geometries
157
158 ## Auxiliary data tables
159
160 Finally there are some table for auxiliary data:
161
162  * `location_property_tiger` - saves housenumber from the Tiger import. Its
163    layout is similar to that of `location_propoerty_osmline`.
164  * `place_class_*` tables are helper tables to facilitate lookup of POIs
165    by their class and type. They exist because it is not possible to create
166    combined indexes with geometries.
167