Uh oh!
There was an error while loading. Please reload this page.
This repository was archived by the owner on Jan 28, 2025. It is now read-only.
- Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathschema.sql
More file actions
Latest commit
307 lines (286 loc) · 13.7 KB
/
Copy pathschema.sql
File metadata and controls
307 lines (286 loc) · 13.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
-- Increment this number any time the schema is changed, and update schemaVersion
-- in BDCS/DB.hs
PRAGMA user_version =4;
-- This describes the schema used by the metadata database (mddb). We
-- considered several options for how to implement the mddb, finally deciding
-- upon sqlite (though, other relational databases would also be fine). We
-- would like the mddb to eventually hold the data for multiple builds of each
-- package from many releases. This could mean hundreds of millions of rows
-- needed to store the files. Thus, the ability to work with a fairly large
-- database is important.
--
-- We evaluated document-based databases like mongodb but found it too slow and
-- a little unwieldy to use for our purposes. We also evaluated key/value
-- systems like redis but found that accessing data was slow unless you add
-- your own index algorithm. And if you're going to do that, you might as well
-- use something that already provides indexing. Add sqlite's ubiquity and
-- the ability to move to another relational database if needed, and the
-- decision was made.
--
-- In general, the design of this database does not worry too much about
-- normal forms. However, we do use a lot of intermediate tables to represent
-- one-to-many relationships as well as ensure that a piece of data only exists
-- in one place in the database. Examples of these intermediate tables are
-- the various *_files tables and the *_key_values tables.
--
-- At the same time, we have sought to not overload the database with tons of
-- unnecessary tables. That is why there is the key_val table and all the
-- associated *_key_values tables. There are lots of pieces of data at all
-- levels (builds, files, etc.) that only exist for a handful of items.
-- Alternately, there are pieces of data that exist with a wide range of
-- possible values. The generic key_val table allows storing this kind of
-- data without making too much of a mess.
-- A project is the database's representation of some upstream that produces
-- a piece of software. This could be as simple as a tarball that gets built
-- into a single RPM, or as complicated as a live OS image, or anything in
-- between. We don't impose any restrictions here on what kind of thing a
-- project can be.
--
-- Starting with this table, we split NEVRA-style information up between here,
-- sources, and builds because it makes sense to do so. At each level, we only
-- store information that does not change between instances of that level. For
-- instance, this table stores the name. All sources released from a given
-- project will have the same name, as will all builds created from those
-- sources.
--
-- At any one time, there will only be one row in this table for a single
-- project. It does not make sense to have several instances.
createtableprojects (
id integerprimary key,
name textnot null unique,
summary textnot null,
description textnot null,
homepage text,
upstream_vcs text
);
-- A source represents a release of a single upstream project (hence the
-- project_id reference). This table continues the theme of spreading NEVRA
-- style information out to several tables. In this table we store the version
-- since that piece is specific to a source.
--
-- Over time, there will be several entries in this table with the same
-- project_id, as an upstream makes several releases and we import them.
--
-- FIXME: Explain source_ref. We're not populating that right now anyway.
createtablesources (
id integerprimary key,
project_id integerreferences projects(id) not null,
license textnot null,
version textnot null,
source_ref textnot null
);
createindexsources_project_id_idxon sources(project_id);
-- A build represents a single successful compilation of a single source (hence
-- the source_id reference). It continues the theme of spreading NEVRA-style
-- information out to several tables. In this table we store the epoch,
-- release, and architecture since those pieces are specific to a build.
--
-- Over time, there could potentially be many entries in the table with the
-- same source_id, depending on how often upstream does releases and how
-- frequently a single release is rebuilt.
--
-- A build also has only a single changelog entry, the entry corresponding to
-- this latest build. Constructing the entire chain of changes for a given
-- project would require grabbing all rows out of this table whose associated
-- source has an associated project with the name you're looking for. It's a
-- little complicated, but it's expected that this sort of operation will not
-- be required often.
--
-- FIXME: Explain build_config_ref and build_env_ref. We're not populating
-- those right now anyway.
createtablebuilds (
id integerprimary key,
source_id integerreferences sources(id) not null,
epoch integer default 0,
release textnot null,
arch textnot null,
build_time textnot null,
changelog blob not null,
build_config_ref textnot null,
build_env_ref textnot null
);
createindexbuilds_source_id_idxon builds(source_id);
-- Associate various types of build signatures with a single build. A build
-- signature could take the form of the RSA or SHA1 header out of a built RPM, or
-- a variety of other formats. Here we store both the type of the signature and
-- the signature itself, so it can be verified by other tools. A single build
-- can have several signatures at the same time.
createtablebuild_signatures (
id integerprimary key,
build_id integerreferences builds(id) not null,
signature_type textnot null,
signature_data blob not null
);
createindexbuild_signatures_build_id_idxon build_signatures(build_id);
-- This is one of the largest tables in the metadata database - the one that
-- stores a row for every file that has been imported. This table stores
-- everything required for recreating a file on disk with the right path and
-- permissions, except for the contents of the file. This is the metadata
-- database. The contents live in the content store.
--
-- It is possible that a single file exists in multiple compilation units
-- (packages, for instance). Thus, the relationship between a file and what
-- contains it must be in some other table. See build_files for more
-- information.
--
-- It is also possible (and in fact, likely) that a single file will exist in
-- multiple builds. Consider two builds of the same source - it is likely that
-- many of the files will be identical, and that only some will change in any
-- meaningful way. It would be nice if we could reduce duplication and only
-- store a new row for a single file when it had real changes. Alas, a file
-- that is identical across two builds will still have a different mtime.
--
-- Thus (for now), each new build imported will result in rows for all its file
-- being created again.
--
-- The content store contains some metadata about the file (size, mode) that is
-- not duplicated here. This table does include mtime, since that is not tracked
-- by the content store (and would cause problems with identitcal files across
-- multiple builds if it did), and user/group, since those are stored here as
-- names instead of UID/GID.
createtablefiles (
id integerprimary key,
pathtextnot null,
file_user textnot null,
file_group textnot null,
mtime integernot null,
cs_object blob,
mode integernot null,
size integernot null,
target text
);
createindexfiles_path_idxon files(path);
-- This table associates a single file with a single source. It allows for a
-- file to be part of several sources at the same time, and for a single source
-- to contain several files.
createtablesource_files (
id integerprimary key,
source_id integerreferences sources(id) not null,
file_id integerreferences files(id) not null
);
createindexsource_files_source_id_idxon source_files(source_id);
createindexsource_files_file_id_idxon source_files(file_id);
-- This table associates a single file with a single build. It allows for a
-- file to be a part of several builds at the same time, and for a single build
-- to contain several files.
createtablebuild_files (
id integerprimary key,
build_id integerreferences builds(id) not null,
file_id integerreferences files(id) not null
);
createindexbuild_files_build_id_idxon build_files(build_id);
createindexbuild_files_file_id_idxon build_files(file_id);
-- This table is a free form key/value association. It allows storing data that
-- doesn't make sense anywhere else, or is more free form in nature, or just
-- doesn't fit with a traditional SQL-based database layout. This style of data
-- can exist at many levels - projects have it, as do sources, builds, and files.
-- The key/value pairs are stored in this table, and then the association with
-- some project or source is created in a specific table. This allows sharing
-- the key/value pair among several builds, or several files, or some combination.
--
-- Primary examples of key/value data are:
--
-- * Associating produced RPMs with a single build. Packages are a concept that
-- exist with RPM and potentially other sources of input, but not all. Thus
-- we do not go out of our way to model them in the database. Using a key/val
-- allows keeping track of what group of RPMs came from a given build without
-- needing extra tables that only make sense sometimes.
-- * Associating files with an RPM. For similar reasons, we use the key/value
-- pairing to keep track of which files make up which RPM.
-- * Keeping track of rpm-provide data.
createtablekey_val (
id integerprimary key,
key_value textnot null,
val_value text,
ext_value text
);
-- for key/val, it's not likely that we'll have a query that is looking up
-- a key name based on the value name. Queries will either be looking for
-- values given a key, or looking for ids based on a key/value pair.
-- So instead of an index on val_value, make the second index on both key
-- and value.
createindexkey_val_key_value_idxon key_val(key_value);
createindexkey_val_val_value_idxon key_val(key_value, val_value);
-- Associate key/value data with an individual project. It is possible for a
-- single project to have many different key/value data pieces, or none.
createtableproject_values (
id integerprimary key,
project_id integerreferences projects(id) not null,
key_val_id integerreferences key_val(id) not null
);
createindexproject_values_project_id_idxon project_values(project_id);
createindexproject_values_key_val_id_idxon project_values(key_val_id);
-- Associate key/value data with an individual source. It is possible for a
-- single source to have many different key/value data pieces, or none.
createtablesource_key_values (
id integerprimary key,
source_id integerreferences sources(id) not null,
key_val_id integerreferences key_val(id) not null
);
createindexsource_key_values_source_id_idxon source_key_values(source_id);
createindexsource_key_values_key_val_id_idxon source_key_values(key_val_id);
-- Associate key/value data with an individual build. It is possible for a
-- single build to have many different key/value data pieces, or none.
createtablebuild_key_values (
id integerprimary key,
build_id integerreferences builds(id) not null,
key_val_id integerreferences key_val(id) not null
);
createindexbuild_key_values_build_id_idxon build_key_values(build_id);
createindexbuild_key_values_key_val_id_idxon build_key_values(key_val_id);
-- Associate key/value data with an individual file. It is possible for a
-- single file to have many different key/value data pieces, or none.
createtablefile_key_values (
id integerprimary key,
file_id integerreferences files(id) not null,
key_val_id integerreferences key_val(id) not null
);
createindexfile_key_values_file_id_idxon file_key_values(file_id);
createindexfile_key_values_key_val_id_idxon file_key_values(key_val_id);
-- Groups of things. e.g., a rpm subpackage, a comps group, a module
-- This differs from file tags in that a group can contain other groups in
-- addition to individual files, and a group can be empty.
createtablegroups (
id integerprimary key,
name textnot null,
group_type textnot null,
build_id integerreferences builds(id) null
);
createindexgroups_name_idxon groups(name);
createtablegroup_files (
id integerprimary key,
group_id integerreferences groups(id) not null,
file_id integerreferences files(id) not null
);
createindexgroup_files_group_id_idxon group_files(group_id);
createindexgroup_files_file_id_idxon group_files(file_id);
-- FIXME how do you prevent cycles in this thing?
createtablegroup_groups (
id integerprimary key,
parent_group_id references groups(id) not null,
child_group_id references groups(id) not null
);
createindexgroup_groups_parent_group_id_idxon group_groups(parent_group_id);
createindexgroup_groups_child_group_id_idxon group_groups(child_group_id);
createtablegroup_key_values (
id integerprimary key,
group_id integerreferences groups(id) not null,
key_val_id integerreferences key_val(id) not null
);
createindexgroup_key_values_group_id_idxon group_key_values(group_id);
createindexgroup_key_values_key_val_id_idxon group_key_values(key_val_id);
createtablerequirements (
id integerprimary key,
req_language textnot null,
req_context textnot null,
req_strength textnot null,
req_expr textnot null
);
createtablegroup_requirements (
id integerprimary key,
group_id integerreferences groups(id) not null,
req_id integerreferences requirements(id) not null
);
createindexgroup_requirements_group_id_idxon group_requirements(group_id);
createindexgroup_requirements_req_id_idxon group_requirements(req_id);
.quit