Assuming that it's ok for the same person to have memberships in multiple location groups and also be on staff at multiple locations, this looks fine.
Something to be careful of is duplicate memberships. Presumably you don't want the same person to have a membership in the same location group, nor be on staff at the same location twice. You need unique indexes to enforce this.
-- Note, with this you don't need a separate index on person_id.
create unique index unique_member_idx
on member(person_id, location_group_id);
-- And you don't need a separate index on person_id.
create unique index unique_staff_idx
on member(person_id, location_id);
You might also want to put a unique index on person.email
, being careful to normalize your email addresses (downcase them, strip leading and trailing whitespace) before inserting or as an insert/update trigger.
For the location settings, unless you're storing bit fields blob
is incorrect; it's for binary data. You could store JSON as text
, but SQLite lacks JSON functionality so querying it would be very slow. I'd recommend a key/value table for your location specific settings.
-- And one for location_group.
create table location_settings (
location_id bigint not null references location(id),
key text not null,
value text not null
);
How you index this depends on how you're going to query it. If you plan on querying the value of a key for all locations like select location_id, value from location_settings where key = ?
then put an index on key
. Otherwise if you'll always query with where location_id = ?
, even with and key = ?
the index on location_id should be fine.
You can add a set of values by inputting the same key for the same location.
insert into location_settings (location_id, key, value)
values (1, 'foo_list', 23), (1, 'foo_list', 42);
Or you can stick to one key and store complex values as JSON.
-- Do not allow duplicate keys.
create unique index location_settings_key_idx
on location_settings(key, location_id);
insert into location_settings (location_id, key, value)
values (1, 'foo_list', '[23, 42]');
A few other notes.
- Store dates as
datetime
or timestamp
. I know SQLite doesn't have a date type, it will ignore it and store a string, but get into the habit now. And store them as ISO 8601.
- Declare everything
not null
unless it specifically needs to be null. This will save you a lot of headache later.
- Don't limit the size of fields in the schema. You're not saving any space. Size limits are a business rule; they change and should be enforced in the app. Use
text
or varchar(255)
.
- DO NOT store passwords in the clear. They should be salted and hashed using a library.