Skip to content

Commit 880885a

Browse files
committed
Initial commit
0 parents  commit 880885a

File tree

11 files changed

+558
-0
lines changed

11 files changed

+558
-0
lines changed

.gitignore

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
## Specific to this project:
2+
.env
3+
*.db
4+
*.sqlite3
5+
6+
## Specific to Mac OS X:
7+
.DS_Store
8+
.AppleDouble
9+
.LSOverride
10+
11+
# OS X thumbnails
12+
._*
13+
14+
## Specific to Windows:
15+
# Windows image file caches
16+
Thumbs.db
17+
ehthumbs.db
18+
19+
# Folder config file
20+
Desktop.ini
21+
22+
## Specific to Ruby:
23+
*.gem
24+
*.rbc
25+
/.config
26+
/coverage/
27+
/InstalledFiles
28+
/pkg/
29+
/spec/reports/
30+
/test/tmp/
31+
/test/version_tmp/
32+
/tmp/
33+
34+
## Ruby documentation cache and generated files:
35+
/.yardoc/
36+
/_yardoc/
37+
/doc/
38+
/rdoc/
39+
40+
## Ruby environment normalisation:
41+
/.bundle/
42+
/lib/bundler/man/
43+
.rvmrc
44+
45+
## Specific to Cloud9 IDE:
46+
.c9revisions
47+
.c9
48+
49+
## Specific to Vim:
50+
[._]*.s[a-w][a-z]
51+
[._]s[a-w][a-z]
52+
*.un~
53+
Session.vim
54+
.netrwhist
55+
*~
56+
57+
## Specific to Sublime Text:
58+
# Cache files for sublime text
59+
*.tmlanguage.cache
60+
*.tmPreferences.cache
61+
*.stTheme.cache
62+
63+
# Workspace files are user-specific
64+
*.sublime-workspace
65+
66+
# sftp configuration file
67+
sftp-config.json
68+
69+
## Specific to RubyMotion:
70+
.dat*
71+
.repl_history
72+
build/

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2014 CodeUnion, Inc. <http://codeunion.io>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Example Database Schemas
2+
3+
This repository contains a handful of example database schemas. We want this
4+
repository to do two things:
5+
6+
1. Serve as a reference for common schema design patterns
7+
2. Give students more exposure to schema-level SQL, e.g.,
8+
`CREATE TABLE`, `CREATE UNIQUE INDEX`, and so on.
9+
10+
## Format of This Repository
11+
12+
Every schema is contained in its own directory. For example, the
13+
[blog_with_tags](blog_with_tags) directory contains a schema for a very basic
14+
blog with support for tagging blog posts. In this example, the schema itself is
15+
contained in a file named
16+
17+
```text
18+
blog_with_tags.postgres.sql
19+
```
20+
21+
which contains raw SQL `CREATE TABLE` statements that define the various tables,
22+
indexes, and associations that make up the database schema.
23+
24+
The file is named `.postgres.sql` because the SQL statements contained inside
25+
follow PostgreSQL's dialect of SQL. Every database engine has its own "dialect"
26+
of SQL, whether the engine MySQL, SQLite3, Microsoft SQL Server, or Oracle.
27+
28+
We'll be adding examples in other dialects as time goes on. If you want to
29+
help the process along, [we welcome pull requests][pull-request-url]
30+
31+
## Schemas in This Repository
32+
33+
### Blog With Tags
34+
35+
The [blog_with_tags](blog_with_tags) schema models a basic blog where users can
36+
publish articles and tag them with arbitrary tags. It defines users, articles,
37+
and tags.
38+
39+
### Blog With Likes
40+
41+
The [blog_with_likes](blog_with_likes) schema models a basic blog where users
42+
can publish new articles or like already-published articles. It defines users,
43+
articles, and likes.
44+
45+
### Question and Answer
46+
47+
The [question_and_answer](question_and_answer) schema models a basic Q&A site
48+
a la Stack Overflow or Yahoo! Answers. It defines users, questions, answers,
49+
and voting.
50+
51+
### Surveys
52+
53+
The [surveys](surveys) schema models a website where users can create surveys
54+
for other users to fill out. It defines users, surveys, survey choices, and
55+
survey responses.
56+
57+
### Reddit
58+
59+
The [reddit](reddit) schema models a Reddit-like site where users submit links
60+
for other to vote and comment on. It defines users, link submissions, voting,
61+
and nested commenting.
62+
63+
### Photo Gallery
64+
65+
The [photo_gallery](photo_gallery) schema models a basic photo gallery. Users
66+
can create albums and upload photos to a specific album.
67+
68+
### Hangman
69+
70+
The [hangman](hangman) schema models a player vs. computer version of
71+
[letter-guessing game Hangman](http://en.wikipedia.org/wiki/Hangman_%28game%29).
72+
It defines users, games, turns, and phrases.
73+
74+
### Tic Tac Toe
75+
76+
The [tic_tac_toe](tic_tac_toe) schema models a collection of tic-tac-toe games.
77+
It defines users, games, and turns.
78+
79+
[pull-request-url]: https://github.com/codeunion/examples-schema/pulls
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
CREATE TABLE users (
2+
id SERIAL PRIMARY KEY,
3+
email VARCHAR(255) NOT NULL,
4+
password_digest VARCHAR(255) NOT NULL,
5+
created_at TIMESTAMP NOT NULL,
6+
updated_at TIMESTAMP NOT NULL
7+
);
8+
9+
CREATE UNIQUE INDEX ON users(email);
10+
11+
CREATE TABLE articles (
12+
id SERIAL PRIMARY KEY,
13+
author_id INTEGER NOT NULL,
14+
title VARCHAR(255) NOT NULL,
15+
body TEXT NOT NULL,
16+
created_at TIMESTAMP NOT NULL,
17+
updated_at TIMESTAMP NOT NULL,
18+
FOREIGN KEY (author_id) REFERENCES users(id)
19+
);
20+
21+
CREATE INDEX ON articles(author_id);
22+
23+
CREATE TABLE likes (
24+
id SERIAL PRIMARY KEY,
25+
article_id INTEGER NOT NULL,
26+
user_id INTEGER NOT NULL,
27+
created_at TIMESTAMP NOT NULL,
28+
updated_at TIMESTAMP NOT NULL,
29+
FOREIGN KEY (article_id) REFERENCES articles(id),
30+
FOREIGN KEY (user_id) REFERENCES users(id)
31+
);
32+
33+
CREATE UNIQUE INDEX ON likes(article_id, user_id);
34+
CREATE INDEX ON likes(user_id);
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
CREATE TABLE users (
2+
id SERIAL PRIMARY KEY,
3+
email VARCHAR(255) NOT NULL,
4+
password_digest VARCHAR(255) NOT NULL,
5+
created_at TIMESTAMP NOT NULL,
6+
updated_at TIMESTAMP NOT NULL
7+
);
8+
9+
CREATE UNIQUE INDEX ON users(email);
10+
11+
CREATE TABLE articles (
12+
id SERIAL PRIMARY KEY,
13+
author_id INTEGER NOT NULL,
14+
title VARCHAR(255) NOT NULL,
15+
body TEXT NOT NULL,
16+
created_at TIMESTAMP NOT NULL,
17+
updated_at TIMESTAMP NOT NULL,
18+
FOREIGN KEY (author_id) REFERENCES users(id)
19+
);
20+
21+
CREATE INDEX ON articles(author_id);
22+
23+
CREATE TABLE tags (
24+
id SERIAL PRIMARY KEY,
25+
name VARCHAR(255) NOT NULL,
26+
created_at TIMESTAMP NOT NULL,
27+
updated_at TIMESTAMP NOT NULL
28+
);
29+
30+
CREATE UNIQUE INDEX ON tags(name);
31+
32+
CREATE TABLE taggings (
33+
id SERIAL PRIMARY KEY,
34+
article_id INTEGER NOT NULL,
35+
tag_id INTEGER NOT NULL,
36+
created_at TIMESTAMP NOT NULL,
37+
updated_at TIMESTAMP NOT NULL,
38+
FOREIGN KEY (article_id) REFERENCES articles(id),
39+
FOREIGN KEY (tag_id) REFERENCES tags(id)
40+
);
41+
42+
CREATE UNIQUE INDEX ON taggings(article_id, tag_id);
43+
CREATE INDEX ON taggings(tag_id);

hangman/hangman.postgres.sql

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
-- In this schema, when a player initiates a new game, the computer would
2+
-- pick one of the entries from the `phrases` table as the phrase-to-guess.
3+
--
4+
-- Every turn or guess would result in a new entry in the `turns` table,
5+
-- containing the letter the player guessed for that turn.
6+
7+
CREATE TABLE users (
8+
id SERIAL PRIMARY KEY,
9+
email VARCHAR(255) NOT NULL,
10+
password_digest VARCHAR(255) NOT NULL,
11+
created_at TIMESTAMP NOT NULL,
12+
updated_at TIMESTAMP NOT NULL
13+
);
14+
15+
CREATE UNIQUE INDEX ON users(email);
16+
17+
CREATE TABLE games (
18+
id SERIAL PRIMARY KEY,
19+
player_id INTEGER NOT NULL,
20+
phrase_id INTEGER NOT NULL,
21+
guess_limit INTEGER NOT NULL,
22+
completed_at TIMESTAMP,
23+
created_at TIMESTAMP NOT NULL,
24+
updated_at TIMESTAMP NOT NULL,
25+
FOREIGN KEY (player_id) REFERENCES users(id),
26+
FOREIGN KEY (phrase_id) REFERENCES phrases(id)
27+
);
28+
29+
CREATE INDEX ON games(player_id);
30+
31+
CREATE TABLE phrases (
32+
id SERIAL PRIMARY KEY,
33+
body VARCHAR(255) NOT NULL
34+
)
35+
36+
CREATE TABLE turns (
37+
id SERIAL PRIMARY KEY,
38+
game_id INTEGER NOT NULL,
39+
letter_guessed CHAR(1) NOT NULL,
40+
created_at TIMESTAMP NOT NULL,
41+
FOREIGN KEY (game_id) REFERENCES games(id)
42+
);
43+
44+
-- For a given game, a player can't guess the same letter twice.
45+
CREATE UNIQUE INDEX ON turns(game_id, letter_guessed);
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
CREATE TABLE users (
2+
id SERIAL PRIMARY KEY,
3+
email VARCHAR(255) NOT NULL,
4+
password_digest VARCHAR(255) NOT NULL,
5+
created_at TIMESTAMP NOT NULL,
6+
updated_at TIMESTAMP NOT NULL
7+
);
8+
9+
CREATE UNIQUE INDEX ON users(email);
10+
11+
CREATE TABLE albums (
12+
id SERIAL PRIMARY KEY,
13+
user_id INTEGER NOT NULL,
14+
name VARCHAR(255) NOT NULL,
15+
created_at TIMESTAMP NOT NULL,
16+
updated_at TIMESTAMP NOT NULL,
17+
FOREIGN KEY (user_id) REFERENCES users(id)
18+
);
19+
20+
CREATE INDEX ON albums(user_id);
21+
22+
CREATE TABLE photos (
23+
id SERIAL PRIMARY KEY,
24+
album_id INTEGER NOT NULL,
25+
filename VARCHAR(255) NOT NULL,
26+
created_at TIMESTAMP NOT NULL,
27+
updated_at TIMESTAMP NOT NULL,
28+
FOREIGN KEY (album_id) REFERENCES albums(id)
29+
);
30+
31+
CREATE INDEX ON photos(album_id);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
CREATE TABLE users (
2+
id SERIAL PRIMARY KEY,
3+
email VARCHAR(255) NOT NULL,
4+
username VARCHAR(255) NOT NULL,
5+
password_digest VARCHAR(255) NOT NULL,
6+
created_at TIMESTAMP NOT NULL,
7+
updated_at TIMESTAMP NOT NULL
8+
);
9+
10+
CREATE UNIQUE INDEX ON users(email);
11+
CREATE UNIQUE INDEX ON users(username);
12+
13+
CREATE TABLE questions (
14+
id SERIAL PRIMARY KEY,
15+
author_id INTEGER NOT NULL,
16+
best_answer_id INTEGER,
17+
title VARCHAR(255) NOT NULL,
18+
body TEXT NOT NULL,
19+
created_at TIMESTAMP NOT NULL,
20+
updated_at TIMESTAMP NOT NULL,
21+
FOREIGN KEY (author_id) REFERENCES users(id),
22+
FOREIGN KEY (best_answer_id) REFERENCES answers(id)
23+
);
24+
25+
CREATE INDEX ON questions(author_id);
26+
27+
CREATE TABLE answers (
28+
id SERIAL PRIMARY KEY,
29+
author_id INTEGER NOT NULL,
30+
question_id INTEGER NOT NULL,
31+
body TEXT NOT NULL,
32+
created_at TIMESTAMP NOT NULL,
33+
updated_at TIMESTAMP NOT NULL,
34+
FOREIGN KEY (author_id) REFERENCES users(id),
35+
FOREIGN KEY (question_id) REFERENCES questions(id)
36+
);
37+
38+
CREATE UNIQUE INDEX ON answers(author_id, question_id);
39+
CREATE INDEX ON answers(question_id);
40+
41+
CREATE TABLE answer_votes (
42+
id SERIAL PRIMARY KEY,
43+
answer_id INTEGER NOT NULL,
44+
voter_id INTEGER NOT NULL,
45+
score INTEGER NOT NULL,
46+
created_at TIMESTAMP NOT NULL,
47+
updated_at TIMESTAMP NOT NULL,
48+
FOREIGN KEY (answer_id) REFERENCES posts(id),
49+
FOREIGN KEY (voter_id) REFERENCES users(id)
50+
);
51+
52+
CREATE UNIQUE INDEX ON answer_votes(answer_id, voter_id);
53+
CREATE INDEX ON answer_votes(voter_id);

0 commit comments

Comments
 (0)