Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 229 KiB |
Before Width: | Height: | Size: 228 KiB After Width: | Height: | Size: 226 KiB |
@ -0,0 +1,49 @@
|
||||
DBMS = Database Management System (e.g. MySQL, MariaDB, PostgreSQL, Oracle, Access, MongoDB)
|
||||
|
||||
SQL:
|
||||
This should be your default option for most applications
|
||||
Relational database with predefined schema
|
||||
Data organized in tables, rows, and columns
|
||||
Uses SQL as a common language, but some features may be DBMS-specific (MySQL vs PostgreSQL, etc.)
|
||||
Well-suited for multi-table transactions
|
||||
|
||||
NoSQL:
|
||||
Useful when you need high-performance at a huge scale, with little or no relation between tables
|
||||
Allows storing data with no schema
|
||||
Well-suited for documents, JSON, time series data, data dumps, and logs
|
||||
Records can have internal structure (such as an array or tree-like structure)
|
||||
Lack of good support for joins can be circumvented by storing joined data multiple times in different records
|
||||
This sacrifices memory for time
|
||||
Maintaining data consistency is more challenging
|
||||
Some NoSQL DMBSs have limited support for joins and transactions
|
||||
|
||||
Note: If you just need to dump a bunch of JSON data (or something similar) from your application and fetch it back at a later time, you may not need a detailed database model. You may just want to store the JSON data directly (which both SQL and NoSQL databases can do).
|
||||
|
||||
SQLite:
|
||||
From their website: "SQLite does not compete with client/server databases. SQLite competes with fopen()"
|
||||
Benefits:
|
||||
Simple to setup
|
||||
Low latency, even for large sequences of SQL statements
|
||||
Transactional
|
||||
Serverless
|
||||
Single data file
|
||||
Lightweight processing
|
||||
Drawbacks:
|
||||
Any write operation requires a lock on the whole database; many simultaneous writes will slow it down
|
||||
Lacks stored procedures
|
||||
Lacks user management (e.g. who has permission to write to which table)
|
||||
|
||||
Transaction:
|
||||
A unit of work on the database (possibly with multiple actions), treated independently of other such units.
|
||||
If you are using a database, you must learn how to use transactions
|
||||
Properties (ACID):
|
||||
Atomic - either all of the transaction takes affect, or none of it (including under power failures and crashes)
|
||||
Consistent - database invariants are maintained (constraints, triggers, referential integrity, etc.)
|
||||
Isolated - transactions are executed as if they were sequential
|
||||
Durable - committed transactions are never forgotten (i.e. they stored to non-volatile memory)
|
||||
|
||||
Basic operations (CRUD) and their associated SQL statements:
|
||||
Create (INSERT)
|
||||
Retrieve (SELECT)
|
||||
Update (UPDATE)
|
||||
Delete (DELETE)
|
@ -0,0 +1,107 @@
|
||||
Naming conventions I'll be using:
|
||||
UpperCamelCase tables and columns
|
||||
Plural table names (less likely to conflict with reserved words)
|
||||
Singular column names
|
||||
Associative table names:
|
||||
The names the other two tables joined by an underscore: either can be singular or plural as the relationship dictates.
|
||||
Primary keys are named [SingularTableName]ID, and identically when appearing as a foreign key.
|
||||
When needed, add a prefix: SourceWarehouseID and DestinationWarehouseID
|
||||
|
||||
Some SQLite specific commands
|
||||
.open CampusVisit.db
|
||||
.tables
|
||||
PRAGMA table_info(TableName);
|
||||
PRAGMA foreign_keys = ON; /* Need this one to define foreign key contraints. */
|
||||
|
||||
CREATE TABLE Users(
|
||||
UserID INTEGER PRIMARY KEY,
|
||||
Name VARCHAR(100) UNIQUE NOT NULL,
|
||||
Email VARCHAR(20) UNIQUE NOT NULL,
|
||||
PasswordHash VARCHAR(64) NOT NULL,
|
||||
IsAdmin BOOLEAN NOT NULL,
|
||||
IsFaculty BOOLEAN NOT NULL,
|
||||
IsCoordinator BOOLEAN NOT NULL,
|
||||
Availability INTEGER DEFAULT -9223372036854775808 /* 64 bits. LSB is Sunday 8am, then 9am, 10, ... Monday 8am, 9am, .... Sign bit is "other time" category. */
|
||||
);
|
||||
|
||||
CREATE TABLE Visits(
|
||||
VisitID INTEGER PRIMARY KEY,
|
||||
UserID INTEGER, /* DEFAULT NULL is implicit in SQLite. NULL values are allowed with the foreign key. */
|
||||
StudentInfo VARCHAR(100) NOT NULL DEFAULT '',
|
||||
OtherVisitors VARCHAR(100) NOT NULL DEFAULT '',
|
||||
Hometown VARCHAR(50) NOT NULL DEFAULT '',
|
||||
Day VARCHAR(10) NOT NULL, /* YYYY-MM-DD */
|
||||
Availability INTEGER NOT NULL DEFAULT 0, /* Same format as Users.Availability */
|
||||
DecidedTime INTEGER, /* Same format as Users.Availability */
|
||||
Status VARCHAR(9) CHECK(Status IN ('proposed','assigned','confirmed','completed','canceled')) NOT NULL DEFAULT 'proposed',
|
||||
Notes VARCHAR(500) NOT NULL DEFAULT '',
|
||||
NotificationFrequency INTEGER NOT NULL DEFAULT 2,
|
||||
FOREIGN KEY(UserID) REFERENCES Users(UserID)
|
||||
);
|
||||
|
||||
CREATE TABLE Visits_Users (
|
||||
VisitID INTEGER,
|
||||
UserID INTEGER,
|
||||
Willingness VARCHAR(10) CHECK(Willingness IN ('cannot', 'prefer not', 'can do')) NOT NULL, /* unknown if pair is missing from the table */
|
||||
PRIMARY KEY (VisitID, UserID),
|
||||
FOREIGN KEY(VisitID) REFERENCES Visits(VisitID),
|
||||
FOREIGN KEY(UserID) REFERENCES Users(UserID)
|
||||
);
|
||||
|
||||
CREATE TABLE Settings(
|
||||
Key VARCHAR(100) PRIMARY KEY,
|
||||
Value VARCHAR(100) NOT NULL DEFAULT ''
|
||||
);
|
||||
|
||||
Initialization:
|
||||
Initial values for global settings (hyperlink lifetime and notification frequency)
|
||||
INSERT INTO Settings VALUES ('HyperlinkLifetime','7');
|
||||
INSERT INTO Settings VALUES ('CoordinatorNotificationFrequency','3');
|
||||
Login screen:
|
||||
Check username/password
|
||||
SELECT COUNT() FROM Users WHERE Email='mkowalcz@nmu.edu' AND PasswordHash='secret';
|
||||
Visits tab:
|
||||
Create new visit
|
||||
INSERT INTO Visits (StudentInfo,Day) VALUES ('Joe Bloggs, Major: CS', '2025-04-15');
|
||||
Get list of all visits, joined with faculty guides
|
||||
SELECT Visits.VisitID,Visits.StudentInfo,Users.name FROM Visits LEFT JOIN Users ON Visits.UserID=Users.UserID;
|
||||
Delete a visit
|
||||
DELETE FROM Visits WHERE VisitID='1';
|
||||
|
||||
Visit detail window:
|
||||
Get committment levels for all faculty for a given visit
|
||||
SELECT VisitID, Users.UserID, Name, Email FROM Visits_Users INNER JOIN Users ON Visits_Users.UserID=Users.UserID WHERE VisitID=2;
|
||||
Find intersection of visit availability with each faculty availability
|
||||
SELECT Users.UserID, Name, Visits.Availability & Users.Availability FROM Visits INNER JOIN Users WHERE VisitID=1; /* Note that this is using the bitwise and operator "&" because of the way we are storing availability. */
|
||||
Set email frequency for a particular visit
|
||||
UPDATE Visits SET NotificationFrequency=4 WHERE VisitID=2;
|
||||
Set committment level for a given faculty member
|
||||
INSERT INTO Visits_Users VALUES (1,1,'prefer not');
|
||||
Claim a visit and a time
|
||||
UPDATE Visits SET DecidedTime=4, Status='assigned' WHERE VisitID=1 AND Status='proposed';
|
||||
INSERT INTO Visits_Users VALUES (1,1,'can do') ON CONFLICT (VisitID,UserID) DO UPDATE SET Willingness='can do' WHERE (VisitID,UserID)=(1,1);
|
||||
Update visit details
|
||||
UPDATE Visits SET UserID=1 WHERE VisitID=3;
|
||||
User tab:
|
||||
Get list of users, including faculty availability
|
||||
SELECT * FROM Users;
|
||||
Create new user
|
||||
INSERT INTO Users(Name,Email,PasswordHash,IsAdmin,IsFaculty,IsCoordinator) VALUES ('DrKow', 'mkowalcz@nmu.edu', 'secret', TRUE, TRUE, TRUE);
|
||||
INSERT INTO Users(Name,Email,PasswordHash,IsAdmin,IsFaculty,IsCoordinator) VALUES ('Randy', 'rappleto@nmu.edu', 'secret', FALSE, TRUE, FALSE);
|
||||
Update user attributes
|
||||
UPDATE Users SET PasswordHash='secret',IsAdmin=TRUE WHERE Name='DrKow';
|
||||
Update faculty availability
|
||||
UPDATE Users SET Availability=-9223372036854775801 WHERE Email='rappleto@nmu.edu';
|
||||
Delete user
|
||||
DELETE FROM Users WHERE UserID=2;
|
||||
Update global settings
|
||||
UPDATE Settings SET Value='5' WHERE Key='HyperlinkLifetime';
|
||||
UPDATE Settings SET Value='5' WHERE Key='CoordinatorNotificationFrequency';
|
||||
|
||||
References:
|
||||
https://stackoverflow.com/questions/7662/database-table-and-column-naming-conventions
|
||||
https://dev.to/ovid/database-naming-standards-2061
|
||||
https://stackoverflow.com/questions/3037188/naming-of-boolean-column-in-database-table
|
||||
https://stackoverflow.com/questions/2300356/using-a-single-row-configuration-table-in-sql-server-database-bad-idea
|
||||
https://www.sqlite.org/foreignkeys.html
|
||||
https://www.sqlite.org/lang.html
|