List of commits:
Subject Hash Author Date (UTC)
Progress on the SQL chapter. e13cddc35a709c6714a90b21d8ed8db6b037793c aubert@math.cnrs.fr 2018-05-23 05:12:21
Started type some relational model examples in latex, reviewed chapter 1 and 2. 1ddf3000e0cb4f8f02b2b2de1ffd8ae14a81c9dc aubert@math.cnrs.fr 2018-05-22 21:09:12
Finished correcting Chapter 1. Added a preamble and tweaked a lot (math, references, titles of subsubsections, etc.) acdd1bb083cd6985763afd9b77e1b7995dc1ebd7 aubert@math.cnrs.fr 2018-05-22 07:02:51
Cleaning latex dependencies: removed colors, fonts, etc., added header and footer. b4c1232d6091e12bc2cdf038529921143a55b758 aubert@math.cnrs.fr 2018-05-22 05:06:04
Putting all latex material aside, changing class. e43fb54e6ecb0ec4669ed16feba940b47ee3e35c aubert@math.cnrs.fr 2018-05-21 15:14:48
Gathering references, fixing many small typos, adding references in bib. 4f5281a0770f07d2f48f36462ab25f0a3945f4e0 aubert@math.cnrs.fr 2018-05-21 04:54:59
Finished merging exercises into lecture notes! 36e1f79080a8ac56837632bcac2c119fc3efa24f aubert@math.cnrs.fr 2018-05-20 18:50:54
Almost done with the homeworks! f82824a2ca9769a0ecf8fc75d6bf1cae1ef3c7a4 aubert@math.cnrs.fr 2018-05-20 05:23:43
Travail sur intégration des exos dans les notes. c5a6676f85953c7bec9bb2de99bed3552ecf52af aubert@math.cnrs.fr 2018-05-20 05:04:30
Les exercises compilent :-) d4230fce5210d1d8905a42d11634e49e82217541 aubert@math.cnrs.fr 2018-05-19 19:09:56
Progrès sur exercises. 40dd86cdc624209a2282d4437921f46325c2cfa1 aubert@math.cnrs.fr 2018-05-19 18:34:07
Working on exercises. 42549c8d28249f1ecf85dd21f6d004ae63c533ad aubert@math.cnrs.fr 2018-05-19 05:43:04
Working on incorporating the exercises. f32148faeb8b11425fe9a57770db9bc85ae02c34 aubert@math.cnrs.fr 2018-05-19 04:51:37
working on sum for exo. 5fb55d2c31b06161ade3a7cae707485d8c02447a aubert@math.cnrs.fr 2018-05-18 21:12:56
Adding various small notes. 5eac6e0b19441fca9a3f70f239d5cbbc4d769976 aubert@math.cnrs.fr 2018-05-17 20:37:14
First pass over! ea1e4f6ddabd91287d10384dc8f28565a762526b aubert@math.cnrs.fr 2018-05-17 19:26:28
Working on notes on normal forms. 58bfcedc6bd6336592a5f93a43ffc0aaf64fa8f6 aubert@math.cnrs.fr 2018-05-16 16:40:12
Initial commit, draft of lecture notes. 200d2739bca881d60c7c9381b16f5a4d6384ff29 aubert@math.cnrs.fr 2018-05-16 15:35:36
Commit e13cddc35a709c6714a90b21d8ed8db6b037793c - Progress on the SQL chapter.
Author: aubert@math.cnrs.fr
Author date (UTC): 2018-05-23 05:12
Committer name: aubert@math.cnrs.fr
Committer date (UTC): 2018-05-23 05:12
Parent(s): 1ddf3000e0cb4f8f02b2b2de1ffd8ae14a81c9dc
Signer:
Signing key:
Signing status: N
Tree: 64bf9d36032da21346c370449e190a5578ba24b9
File Lines added Lines deleted
notes/00_sum.md 243 112
notes/img/rel_mod/BOOK_Exo.tex 12 15
notes/img/rel_mod/BOOK_Sol.tex 13 16
notes/img/rel_mod/CAR.tex 19 23
notes/img/rel_mod/CINEMA.tex 36 43
notes/img/rel_mod/EMPLOYEE.tex 28 34
notes/img/rel_mod/PROF_DEPARTMENT.tex 28 0
notes/img/rel_mod/TRAIN_Exo.tex 9 12
notes/img/rel_mod/template.tex 58 45
File notes/00_sum.md changed (mode: 100644) (index e0f3acb..43c6cc9)
... ... On top of the [references](references) and of the "resources" listed at the begi
104 104 - Add title to problem, and solve their naming / referencing issue. - Add title to problem, and solve their naming / referencing issue.
105 105 - Check with `jhove 00_sum.pdf`, `pdfinfo 00_sum.pdf` the validity of the document. - Check with `jhove 00_sum.pdf`, `pdfinfo 00_sum.pdf` the validity of the document.
106 106 - Compress / optimize output? - Compress / optimize output?
107 - Make better makefile (compile images in latex, clean up, etc.).
107 108
108 109 # Introduction # Introduction
109 110
 
... ... TICKETS(Id (PK), ShowTimeId (FK to SHOWTIME.Id), Price)
705 706 - [@Textbook6, Ch. 4--5], [@Textbook7, Ch. 6--7] describes `SQL`, not one of its implementation. - [@Textbook6, Ch. 4--5], [@Textbook7, Ch. 6--7] describes `SQL`, not one of its implementation.
706 707 - @problem:installation and @problem:sqldoc contain a list of useful links. - @problem:installation and @problem:sqldoc contain a list of useful links.
707 708 - To compare DBMS, you can look at their features, at <https://en.wikipedia.org/wiki/Comparison_of_relational_database_management_systems>, and at their popularity at <https://db-engines.com/en/ranking> and <https://www.eversql.com/most-popular-databases-in-2018-according-to-stackoverflow-survey/> (if you sum up MySQL and MariaDB, they are first in both). - To compare DBMS, you can look at their features, at <https://en.wikipedia.org/wiki/Comparison_of_relational_database_management_systems>, and at their popularity at <https://db-engines.com/en/ranking> and <https://www.eversql.com/most-popular-databases-in-2018-according-to-stackoverflow-survey/> (if you sum up MySQL and MariaDB, they are first in both).
709 - MySQL and MariaDB have some differences, you can look them up at <https://mariadb.com/kb/en/library/mariadb-vs-mysql-features/> and <https://mariadb.com/kb/en/library/mariadb-vs-mysql-compatibility/>.
710
711 This chapter will be "code-driven": the code will illustrate and help you understand some concepts.
712 You may want to have a look at @problem:installation, in the [problem section](#sec:gettingstartedwithmysql), as early as possible in this lecture.
708 713
709 714 ## Actors ## Actors
710 715
 
... ... The three last sublanguages being dubbed "**D**ata **M**anipulation **L**anguage
733 738
734 739 #### Yet another vocabulary #### Yet another vocabulary
735 740
736
737 741 | "Common" / Relational | SQL | | "Common" / Relational | SQL |
738 742 | :--: | :--: | | :--: | :--: |
739 743 | "Database" | Schema | | "Database" | Schema |
 
... ... Type and domains are two different things in some implementations, cf. for insta
759 763 #### Syntax #### Syntax
760 764
761 765 - A programming language: strict, cryptic error messages, tricky, evolves - A programming language: strict, cryptic error messages, tricky, evolves
762 - SQL is "kind of" case-insensitive^[The SQL keywords are case-insensitive, but the table and schema names are sometimes case-sensitive, it depends of the actual implementation.], doesn't care about spaces and new lines
766 - SQL is "kind of" case-insensitive^[The SQL keywords are case-insensitive, but the table and schema names are sometimes case-sensitive, it depends of the actual implementation. For instance, MySQL is completely case-insensitive (reserved words, tables, attributes), MariaDB isn't (case for table names matter).], doesn't care about spaces and new lines
763 767 - Comments are with `--` or `/* …*/` - Comments are with `--` or `/* …*/`
764 768 - Every statement ends with a `;` - Every statement ends with a `;`
765 769 - Syntax is in @problem:sqldoc. - Syntax is in @problem:sqldoc.
 
... ... Type and domains are two different things in some implementations, cf. for insta
768 772
769 773 ## First Commands ## First Commands
770 774
771 ~~~{.sql}
775 ~~~{.sqlmysql, .numberLines}
772 776 CREATE SCHEMA HW_FACULTY; CREATE SCHEMA HW_FACULTY;
773 777
774 /* Or
778 /* Or
775 779 CREATE DATABASE HW_FACUTLY; CREATE DATABASE HW_FACUTLY;
776 780 */ */
777 781
 
... ... CREATE TABLE HW_FACULTY.PROF(
787 791 PRIMARY KEY(Fname, Hiring) PRIMARY KEY(Fname, Hiring)
788 792 ); );
789 793
790 /* Or
794 /* Or, instead of using the fully qualified name HW_FACULTY.PROF, we could have:
791 795 USE HW_FACULTY; USE HW_FACULTY;
792 796 CREATE TABLE PROF(…) CREATE TABLE PROF(…)
793 797 */ */
 
... ... INSERT INTO PROF VALUES (
807 811 ); );
808 812 ~~~ ~~~
809 813
810 Use `DESCRIBE <TableName>` and `SELECT * FROM <TableName>` intensively to see where you are.
811 Use `DROP TABLE <TableName>` and `DROP SCHEMA <SchemaName>` for a "fresh start".
814 The following commands are particularly useful:
815
816 ~~~{.sqlmysql, , .numberLines}
817 SHOW SCHEMAS; -- List the schema
818 SHOW TABLES; -- List the tables in a schema
819 DESCRIBE <TableName>; -- Show the structure of a table
820 SELECT * FROM <TableName> -- List all the rows in a table
821
822 DROP TABLE <TableName>; -- "Drop" (erase) a table
823 DROP SCHEMA <SchemaName>; -- Drop a schema
824
825 DESCRIBE <SQL command>; -- Gives explanations as to how the SQL command is processed
826 ~~~
812 827
813 828 --- ---
814 829
 
... ... f. `CHECK`
823 838
824 839 We know a. and b. from the Relational Model, here comes new constraints that can't be describe in our relations. We know a. and b. from the Relational Model, here comes new constraints that can't be describe in our relations.
825 840
826 ~~~{.sql}
841 ~~~{.sqlmysql, , .numberLines}
827 842 CREATE TABLE HURRICANE( CREATE TABLE HURRICANE(
828 843 Name VARCHAR(25) PRIMARY KEY, Name VARCHAR(25) PRIMARY KEY,
829 844 WindSpeed INT DEFAULT 76, WindSpeed INT DEFAULT 76,
830 845 Above VARCHAR(25) Above VARCHAR(25)
831 846 ); );
832 847 -- WindSpeed INT CHECK (WindSpeed > 74 AND WindSpeed < 500), -- WindSpeed INT CHECK (WindSpeed > 74 AND WindSpeed < 500),
848 -- would be parsed but wouldn't have any effect!
833 849
834 850 CREATE TABLE STATE( CREATE TABLE STATE(
835 Name VARCHAR(25) UNIQUE,
851 Name VARCHAR(25) UNIQUE, -- NULL can be inserted
836 852 Postal_abbr CHAR(2) NOT NULL Postal_abbr CHAR(2) NOT NULL
837 853 ); );
838 854 ~~~ ~~~
839 855
840 - You can insert `NULL` in `UNIQUE` attributes.
841 - `CHECK` constraints are parsed but don't do anything!
856 `MySQL` can output a description of those tables for us:
857
858 ~~~{.sqlmysql}
859 MariaDB [HW_CONSTRAINTS_PART1]> DESCRIBE HURRICANE;
860 +-----------+-------------+------+-----+---------+-------+
861 | Field | Type | Null | Key | Default | Extra |
862 +-----------+-------------+------+-----+---------+-------+
863 | Name | varchar(25) | NO | PRI | NULL | |
864 | WindSpeed | int(11) | YES | | 76 | |
865 | Above | varchar(25) | YES | | NULL | |
866 +-----------+-------------+------+-----+---------+-------+
867 3 rows in set (0.01 sec)
868
869 MariaDB [HW_CONSTRAINTS_PART1]> DESCRIBE STATE;
870 +-------------+-------------+------+-----+---------+-------+
871 | Field | Type | Null | Key | Default | Extra |
872 +-------------+-------------+------+-----+---------+-------+
873 | Name | varchar(25) | NO | PRI | NULL | |
874 | Postal_abbr | char(2) | NO | UNI | NULL | |
875 +-------------+-------------+------+-----+---------+-------+
876 2 rows in set (0.00 sec)
877 ~~~
842 878
843 ~~~{.sql}
879 ~~~{.sqlmysql, .numberLines}
844 880 -- Adding a primary key: -- Adding a primary key:
845 881 ALTER TABLE STATE ADD PRIMARY KEY (Name); ALTER TABLE STATE ADD PRIMARY KEY (Name);
846 882
883 -- Removing the primary key:
884 ALTER TABLE STATE DROP PRIMARY KEY;
885
847 886 -- Adding a UNIQUE constraint -- Adding a UNIQUE constraint
848 887 ALTER TABLE STATE ADD UNIQUE (Postal_abbr); ALTER TABLE STATE ADD UNIQUE (Postal_abbr);
849 888
850 ALTER TABLE STATE MODIFY Postal_abbr CHAR(2);
889 -- Removing a UNIQUE constraint
890 ALTER TABLE STATE DROP INDEX Postal_abbr;
851 891
852 ALTER TABLE STATE DROP INDEX Name;
892 -- Adding the NOT NULL constraint
893 ALTER TABLE STATE MODIFY Postal_abbr CHAR(2) NOT NULL;
894
895 -- Removing the NOT NULL constraint
896 ALTER TABLE STATE MODIFY Postal_abbr CHAR(2);
853 897
854 898 -- Changing the default value -- Changing the default value
855 899 ALTER TABLE HURRICANE ALTER COLUMN WindSpeed SET DEFAULT 74; ALTER TABLE HURRICANE ALTER COLUMN WindSpeed SET DEFAULT 74;
856 900
901 -- Removing the default value
902 ALTER TABLE HURRICANE ALTER COLUMN WindSpeed DROP DEFAULT;
903
857 904 --Adding a foreign key constraint --Adding a foreign key constraint
858 905 ALTER TABLE HURRICANE ADD FOREIGN KEY (Above) REFERENCES STATE(Name); ALTER TABLE HURRICANE ADD FOREIGN KEY (Above) REFERENCES STATE(Name);
859 906 ~~~ ~~~
860 907
861 908 - `NOT NULL` is to some extend part of the datatype. - `NOT NULL` is to some extend part of the datatype.
862 - Note the difference between adding and removing the `NOT NULL` constraint.
909 - Note the difference between adding and removing the `UNIQUE` constraint: in one case, the parenthesis are mandatory, in the other, they would cause an error! In this example, the parenthesis around `(Name)` and `(Postal_abbr)` are mandatory.
863 910 - The datatype of the foreign key has to be the same as what we are referring. - The datatype of the foreign key has to be the same as what we are referring.
864 - The parenthesis around (Name) and (Postal_abbr) to add the primary and foreign keys, and the UNIQUE constraints, are mandatory.
865 911
866 912 A bit of testing: A bit of testing:
867 913
868 ~~~{.sql}
914 ~~~{.sqlmysql, .numberLines}
869 915 INSERT INTO STATE VALUES('Georgia', 'GA'); INSERT INTO STATE VALUES('Georgia', 'GA');
870 916 INSERT INTO STATE VALUES('Texas', 'TX'); INSERT INTO STATE VALUES('Texas', 'TX');
871 917 INSERT INTO STATE VALUES('FLORIDA', 'FL'); INSERT INTO STATE VALUES('FLORIDA', 'FL');
872 UPDATE STATE SET Name = 'Florida' WHERE Postal_abbr = 'FL';
918 UPDATE STATE SET Name = 'Florida'
919 WHERE Postal_abbr = 'FL';
873 920
874 921 -- There's an error with the following request. Why? -- There's an error with the following request. Why?
875 922 INSERT INTO HURRICANE VALUES('Irma', 150, 'FL'); INSERT INTO HURRICANE VALUES('Irma', 150, 'FL');
 
... ... ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint f
881 926
882 927 INSERT INTO HURRICANE VALUES('Harvey', DEFAULT , 'Texas'); INSERT INTO HURRICANE VALUES('Harvey', DEFAULT , 'Texas');
883 928 INSERT INTO HURRICANE VALUES('Irma', 150, 'Florida'); INSERT INTO HURRICANE VALUES('Irma', 150, 'Florida');
884 DELETE FROM HURRICANE WHERE Name = 'Irma';
929 DELETE FROM HURRICANE
930 WHERE Name = 'Irma';
885 931 INSERT INTO HURRICANE VALUES('Irma', 150, 'Georgia'); INSERT INTO HURRICANE VALUES('Irma', 150, 'Georgia');
886 932
887 UPDATE HURRICANE SET Above = 'Georgia' WHERE Name = 'Irma';
933 UPDATE HURRICANE SET Above = 'Georgia'
934 WHERE Name = 'Irma';
888 935
889 936 /* /*
890 937 MariaDB [HW_CONSTRAINTS_PART1]> SELECT * FROM HURRICANE; MariaDB [HW_CONSTRAINTS_PART1]> SELECT * FROM HURRICANE;
 
... ... MariaDB [HW_CONSTRAINTS_PART1]> SELECT * FROM HURRICANE;
897 944 */ */
898 945
899 946 -- There's an error with the following request. Why? -- There's an error with the following request. Why?
900 UPDATE HURRICANE SET Above = 'North Carolina' WHERE Name = 'Irma';
947 UPDATE HURRICANE SET Above = 'North Carolina'
948 WHERE Name = 'Irma';
901 949
902 950 -- Let's patch it, by adding North Carolina to our STATE table. -- Let's patch it, by adding North Carolina to our STATE table.
903 951 INSERT INTO STATE VALUES('North Carolina', 'NC'); INSERT INTO STATE VALUES('North Carolina', 'NC');
904 UPDATE HURRICANE SET Above = 'North Carolina' WHERE Name = 'Irma';
952 UPDATE HURRICANE SET Above = 'North Carolina'
953 WHERE Name = 'Irma';
905 954 ~~~ ~~~
906 955
907 956 ## Foreign Keys ## Foreign Keys
908 957
909 ~~~{.sql}
958 ~~~{.sqlmysql, .numberLines}
910 959 CREATE TABLE STORM( CREATE TABLE STORM(
911 960 Name VARCHAR(25) PRIMARY KEY, Name VARCHAR(25) PRIMARY KEY,
912 961 Kind ENUM('Tropical Storm', 'Hurricane'), Kind ENUM('Tropical Storm', 'Hurricane'),
 
... ... CREATE TABLE STATE(
926 975 ON UPDATE CASCADE ON UPDATE CASCADE
927 976 ); );
928 977
929
978
930 979 INSERT INTO STORM VALUES('Harvey', 'Hurricane', 130, '2017-08-17'); INSERT INTO STORM VALUES('Harvey', 'Hurricane', 130, '2017-08-17');
931 980 -- In the following, the entry gets created, but date is 0000-00-00! -- In the following, the entry gets created, but date is 0000-00-00!
932 981 INSERT INTO STORM VALUES('Dummy', 'Hurricane', 120, '2017-17-08'); INSERT INTO STORM VALUES('Dummy', 'Hurricane', 120, '2017-17-08');
 
... ... INSERT INTO STORM VALUES('Dummy', 'Hurricane', 120, '2017-17-08');
934 983 INSERT INTO STORM VALUES('Dummy2', 'Hurricane', 120, DATE'2017-17-08'); INSERT INTO STORM VALUES('Dummy2', 'Hurricane', 120, DATE'2017-17-08');
935 984 -- The next one sets NULL for DATE. -- The next one sets NULL for DATE.
936 985 INSERT INTO STORM VALUES('Irma', 'Tropical Storm', 102, DEFAULT); INSERT INTO STORM VALUES('Irma', 'Tropical Storm', 102, DEFAULT);
986 ~~~
987
988 MySQL will always notify you if there is an error in a date attribute
989
990 ~~~{.sqlmysql, .numberLines}
937 991
938 992 INSERT INTO STATE VALUES('Georgia', 'GA', NULL); INSERT INTO STATE VALUES('Georgia', 'GA', NULL);
939 993 INSERT INTO STATE VALUES('Texas', 'TX', NULL); INSERT INTO STATE VALUES('Texas', 'TX', NULL);
940 994 INSERT INTO STATE VALUES('Florida', 'FL', NULL); INSERT INTO STATE VALUES('Florida', 'FL', NULL);
941 995
942 996 -- This instruction is not using the primary key, is that a problem? -- This instruction is not using the primary key, is that a problem?
943 UPDATE STATE SET Affected_by = 'Harvey' WHERE Name = 'Georgia';
997 UPDATE STATE SET Affected_by = 'Harvey'
998 WHERE Name = 'Georgia';
944 999
945 1000 UPDATE STORM SET Name = 'Harley' WHERE Name = 'Harvey'; UPDATE STORM SET Name = 'Harley' WHERE Name = 'Harvey';
946 DELETE FROM STORM WHERE Name = 'Harley';
1001 DELETE FROM STORM
1002 WHERE Name = 'Harley';
947 1003 ~~~ ~~~
948 1004
949 1005 ## Foreign Keys Restrictions ## Foreign Keys Restrictions
950 1006
951 ~~~{.sql}
1007 ~~~{.sqlmysql, .numberLines}
952 1008 CREATE TABLE F_Key( CREATE TABLE F_Key(
953 1009 Attribute VARCHAR(25) PRIMARY KEY Attribute VARCHAR(25) PRIMARY KEY
954 1010 ); );
 
... ... SELECT * FROM Table_cascade;
1005 1061 SELECT * FROM Table_set_null; SELECT * FROM Table_set_null;
1006 1062
1007 1063 -- The following will fail because of the Table_default table: -- The following will fail because of the Table_default table:
1008 UPDATE F_Key SET Attribute = 'After Update' WHERE Attribute = 'First Test';
1009 DELETE FROM F_Key WHERE Attribute = 'First Test';
1064 UPDATE F_Key SET Attribute = 'After Update'
1065 WHERE Attribute = 'First Test';
1066 DELETE FROM F_Key
1067 WHERE Attribute = 'First Test';
1010 1068
1011 1069 -- Let us drop this table, and try again. -- Let us drop this table, and try again.
1012 1070 DROP TABLE Table_default; DROP TABLE Table_default;
 
... ... DROP TABLE Table_default;
1014 1072
1015 1073 --- ---
1016 1074
1017 ~~~{.sql}
1075 ~~~{.sqlmysql, .numberLines}
1018 1076 -- The following fails too, this time because of the Table_restrict table: -- The following fails too, this time because of the Table_restrict table:
1019 UPDATE F_Key SET Attribute = 'After Update' WHERE Attribute = 'First Test';
1020 DELETE FROM F_Key WHERE Attribute = 'First Test';
1077 UPDATE F_Key SET Attribute = 'After Update'
1078 WHERE Attribute = 'First Test';
1079 DELETE FROM F_Key
1080 WHERE Attribute = 'First Test';
1021 1081
1022 1082 -- Let us drop this table, and try again. -- Let us drop this table, and try again.
1023 1083 DROP TABLE Table_restrict; DROP TABLE Table_restrict;
 
... ... INSERT INTO F_Key VALUES('Second Test');
1052 1112 INSERT INTO Table_cascade VALUES('Default', 'Second Test'); INSERT INTO Table_cascade VALUES('Default', 'Second Test');
1053 1113 INSERT INTO Table_set_null VALUES('Restrict', 'Second Test'); INSERT INTO Table_set_null VALUES('Restrict', 'Second Test');
1054 1114
1055 DELETE FROM F_Key WHERE Attribute = 'Second Test';
1115 DELETE FROM F_Key
1116 WHERE Attribute = 'Second Test';
1056 1117
1057 SELECT * FROM Table_cascade;
1058 SELECT * FROM Table_set_null;
1118 /*
1119 MariaDB [HW_CONSTRAINTS_PART3]> SELECT * FROM Table_cascade;
1120 +------------+--------------+
1121 | Attribute1 | Attribute2 |
1122 +------------+--------------+
1123 | Cascade | After Update |
1124 +------------+--------------+
1125 1 row in set (0.00 sec)
1126
1127 MariaDB [HW_CONSTRAINTS_PART3]> SELECT * FROM Table_set_null;
1128 +------------+------------+
1129 | Attribute1 | Attribute2 |
1130 +------------+------------+
1131 | Restrict | NULL |
1132 | Set null | NULL |
1133 +------------+------------+
1134 2 rows in set (0.00 sec)
1135 */
1059 1136 ~~~ ~~~
1060 1137
1061 1138 --- ---
 
... ... SELECT * FROM Table_set_null;
1066 1142 #### Construction #### Construction
1067 1143
1068 1144 - Remember, we start by creating a schema and tables inside of it. - Remember, we start by creating a schema and tables inside of it.
1069 - What if foreign keys are mutually dependent?
1145 - What if foreign keys are mutually dependent? What if we have something like:
1070 1146
1071 ~~~{.sql}
1147 ![
1148 PROF(Login (PK), Name, Department (FK to DEPARTMENT.Code))
1149 DEPARTMENT(Code (PK), Name, Head (FK to PROF.Login))
1150 ](img/rel_mod/PROF_DEPARTMENT.svg){ width=100% }
1151 \
1152
1153 ~~~{.sqlmysql, .numberLines}
1072 1154 CREATE TABLE PROF( CREATE TABLE PROF(
1073 1155 Login VARCHAR(25) PRIMARY KEY, Login VARCHAR(25) PRIMARY KEY,
1074 1156 Name VARCHAR(25), Name VARCHAR(25),
 
... ... CREATE TABLE DEPARTMENT(
1083 1165 ON UPDATE CASCADE ON UPDATE CASCADE
1084 1166 ); );
1085 1167
1086 ALTER TABLE PROF ADD FOREIGN KEY (Department) REFERENCES DEPARTMENT(Code);
1168 ALTER TABLE PROF ADD FOREIGN KEY (Department)
1169 REFERENCES DEPARTMENT(Code);
1087 1170 ~~~ ~~~
1088 1171
1089 1172 Note the structure of the `ALTER TABLE` command: Note the structure of the `ALTER TABLE` command:
1090 1173
1091 - … `KEY Department REFERENCES Code;`: error
1092 - … `KEY (Department) REFERENCES (Code);`: error
1093 - … `KEY PROF(Department) REFERENCES DEPARTMENT(Code);`: ok
1174 - … `KEY Department REFERENCES Code;`⇒ error
1175 - … `KEY (Department) REFERENCES (Code);`⇒ error
1176 - … `KEY PROF(Department) REFERENCES DEPARTMENT(Code);` ⇒ ok
1094 1177
1095 ~~~{.sql}
1178 ~~~{.sqlmysql, .numberLines}
1096 1179 CREATE TABLE STUDENT( CREATE TABLE STUDENT(
1097 1180 Login VARCHAR(25) PRIMARY KEY, Login VARCHAR(25) PRIMARY KEY,
1098 1181 Name VARCHAR(25), Name VARCHAR(25),
 
... ... CREATE TABLE STUDENT(
1106 1189
1107 1190 We can insert multiple values at once: We can insert multiple values at once:
1108 1191
1109 ~~~{.sql}
1192 ~~~{.sqlmysql}
1110 1193 INSERT INTO DEPARTMENT VALUES INSERT INTO DEPARTMENT VALUES
1111 1194 ('MATH', 'Mathematics', NULL), ('MATH', 'Mathematics', NULL),
1112 1195 ('CS', 'Computer Science', NULL); ('CS', 'Computer Science', NULL);
 
... ... INSERT INTO DEPARTMENT VALUES
1114 1197
1115 1198 We can specify which attributes we are giving: We can specify which attributes we are giving:
1116 1199
1117 ~~~{.sql}
1200 ~~~{.sqlmysql}
1118 1201 INSERT INTO DEPARTMENT (Code, Name) VALUES INSERT INTO DEPARTMENT (Code, Name) VALUES
1119 1202 ('CYBR', 'Cyber Secturity'); ('CYBR', 'Cyber Secturity');
1120 1203 ~~~ ~~~
1121 1204
1122 1205 And we can even specify the order (even the trivial one): And we can even specify the order (even the trivial one):
1123 1206
1124 ~~~{.sql}
1207 ~~~{.sqlmysql, .numberLines}
1125 1208 INSERT INTO PROF (Login, Department, Name) VALUES INSERT INTO PROF (Login, Department, Name) VALUES
1126 1209 ('caubert', 'CS', 'Clément Aubert'); ('caubert', 'CS', 'Clément Aubert');
1127 1210
 
... ... INSERT INTO STUDENT (Login, Name, Registered, Major) VALUES
1138 1221 ('caubert', 'Clément Aubert', NULL, 'CYBR'); ('caubert', 'Clément Aubert', NULL, 'CYBR');
1139 1222 ~~~ ~~~
1140 1223
1141 Note the date litterals.
1142
1143 #### A note on the differences between MySQL and MariaDB {#differenceMySQLMariaDB}
1144
1145 - MySQL is completely case-insensitive (reserved words, tables, attributes), MariaDB isn't (case for tables matter).
1146 - MySQL will always notify you if there is an error in a date attribute
1147
1148 Refer to <https://mariadb.com/kb/en/library/mariadb-vs-mysql-features/> and <https://mariadb.com/kb/en/library/mariadb-vs-mysql-compatibility/> for a full list.
1149
1224 Note the date literals.
1150 1225
1151 1226 ## A First Look at Conditions ## A First Look at Conditions
1152 1227
1153 1228 Order of clauses does not matter, not even for optimization purpose. Order of clauses does not matter, not even for optimization purpose.
1154 1229
1155 1230
1156 ~~~{.sql}
1231 ~~~{.sqlmysql}
1157 1232 UPDATE <table> UPDATE <table>
1158 1233 SET <attribute1> = <value1>, <attribute2> = <value2>, … SET <attribute1> = <value1>, <attribute2> = <value2>, …
1159 1234 WHERE <condition>; WHERE <condition>;
 
... ... WHERE <condition>;
1161 1236 SELECT <attribute list, called projection attributes> SELECT <attribute list, called projection attributes>
1162 1237 FROM <table list> FROM <table list>
1163 1238 WHERE <condition>; WHERE <condition>;
1239
1240 DELETE FROM <table list>
1241 WHERE <condition>;
1164 1242 ~~~ ~~~
1165 1243
1166 1244 Conditions can Conditions can
1167 1245
1168 1246 - be compounded - be compounded
1169 - `condition1 AND condition2 AND condition3`
1247 - `condition1 AND condition2`
1170 1248 - `condition1 OR condition2` - `condition1 OR condition2`
1171 1249 - `NOT condition` - `NOT condition`
1250 - Usage of parenthesis is possible
1172 1251 - be trivial / empty - be trivial / empty
1173 - use regular expressions (escape character is `\`).
1252 - use regular expressions
1253 - uses the expression `LIKE`,
1254 - escape character is `\`,
1255 - `_` will match one character (any character), `%` will match any number of character,
1256 - advanced regular expression possible using the `REGEXP` keyword.
1174 1257
1175 ~~~{.sql}
1176 UPDATE Department SET Head = 'aturing' WHERE Code = 'MATH';
1258 ~~~{.sqlmysql}
1259 SELECT Login FROM STUDENT;
1177 1260
1178 UPDATE Department SET Head = 'bgates' WHERE Code = 'CS' OR NOT Code = 'CYBR';
1261 UPDATE Department SET Head = 'aturing'
1262 WHERE Code = 'MATH';
1179 1263
1180 SELECT Login FROM STUDENT WHERE Major = 'CYBR';
1264 UPDATE Department SET Head = 'bgates'
1265 WHERE Code = 'CS' OR Code = 'CYBR';
1181 1266
1182 SELECT Login, Name FROM PROF WHERE Department = 'CS';
1267 SELECT Login FROM STUDENT
1268 WHERE NOT Major = 'CYBR';
1183 1269
1184 SELECT Login FROM STUDENT WHERE Major = 'CYBR' AND Registered > DATE'20121001';
1270 SELECT Login, Name FROM PROF
1271 WHERE Department = 'CS';
1185 1272
1186 SELECT Login FROM STUDENT;
1273 SELECT Login FROM STUDENT
1274 WHERE Major = 'CYBR'
1275 AND Registered > DATE'20121001';
1187 1276
1188 SELECT Login FROM STUDENT WHERE Name LIKE 'Ava%';
1277 SELECT Login FROM STUDENT
1278 WHERE Name LIKE 'Ava%';
1189 1279
1190 SELECT Name FROM PROF WHENE Login LIKE '_aubert';
1280 SELECT Name FROM PROF
1281 WHERE Login LIKE '_aubert';
1191 1282 ~~~ ~~~
1192 1283
1193 1284 --- ---
1194 1285
1195 1286 ## Various Tools ## Various Tools
1196 1287
1197 For `DISTINCT`, `ALL` and `UNION`, cf. [@Textbook6, 4.3.4]. For `ORDER BY` , cf. [@Textbook6, 4.3.6].
1198 For aggregate functions, cf. [@Textbook6, 5.1.7].
1288 For `DISTINCT`, `ALL` and `UNION`, cf. [@Textbook6, 4.3.4] or [@Textbook7, 6.3.4].
1289 For `ORDER BY` , cf. [@Textbook6, 4.3.6] or [@Textbook7, 6.3.6].
1290 For aggregate functions, cf. [@Textbook6, 5.1.7] or [@Textbook7, 7.1.7].
1199 1291
1200 ### DISTINCT / ALL and Union
1292 ### DISTINCT / ALL
1201 1293
1202 Note: SQL treats tables as multi-set, there can be repetitions in the tables.
1294 The result of a `SELECT` query, for instance, is a table, and SQL treats tables as multi-set, hence there can be repetitions in the result of a query, but we can remove them:
1203 1295
1204 ~~~{.sql}
1296 ~~~{.sqlmysql}
1205 1297 SELECT DISTINCT Major FROM STUDENT; SELECT DISTINCT Major FROM STUDENT;
1206 1298 ~~~ ~~~
1207 1299
1208 The default behaviour is `ALL`, but we can declare it explicitely.
1300 The default behaviour is equivalent to specifying `ALL`, and it display the duplicates.
1301
1302 ### UNION
1209 1303
1210 ~~~{.sql}
1304 ~~~{.sqlmysql}
1211 1305 (SELECT Login FROM STUDENT) UNION (SELECT Login FROM PROF); (SELECT Login FROM STUDENT) UNION (SELECT Login FROM PROF);
1212 1306 ~~~ ~~~
1213 1307
1214 There is also `INTERSECT` and `EXCEPT` in the specification, but MariaDB and MySQL do not implement them.
1308 There is also `INTERSECT` and `EXCEPT` in the specification, but MySQL does not implement them (cf. <https://en.wikipedia.org/wiki/Comparison_of_relational_database_management_systems#Database_capabilities>).
1215 1309
1216 1310 ### ORDER BY ### ORDER BY
1217 1311
1218 1312 You can have `ORDER BY` specifications: You can have `ORDER BY` specifications:
1219 1313
1220 ~~~{.sql}
1221 SELECT Login FROM GRADE WHERE Grade > 3.0 ORDER BY Grade;
1314 ~~~{.sqlmysql}
1315 SELECT Login FROM GRADE
1316 WHERE Grade > 3.0
1317 ORDER BY Grade;
1222 1318
1223 SELECT Login FROM GRADE WHERE Grade > 3.0 ORDER BY Grade DESC;
1319 SELECT Login FROM GRADE
1320 WHERE Grade > 3.0
1321 ORDER BY Grade DESC;
1224 1322
1225 SELECT Login, Major FROM STUDENT ORDER BY Major, Name;
1323 SELECT Login, Major FROM STUDENT
1324 ORDER BY Major, Name;
1226 1325 ~~~ ~~~
1227 1326
1228 1327 ### Aggregate functions ### Aggregate functions
1229 1328
1230 1329 You can use `MAX`, `SUM`, `MIN`, `AVG`, `COUNT`: You can use `MAX`, `SUM`, `MIN`, `AVG`, `COUNT`:
1231 1330
1232 ~~~{.sql}
1331 ~~~{.sqlmysql}
1233 1332 SELECT MAX(Registered) FROM STUDENT; SELECT MAX(Registered) FROM STUDENT;
1234 1333
1235 1334 SELECT COUNT(Name) FROM STUDENT; SELECT COUNT(Name) FROM STUDENT;
 
... ... SELECT COUNT(DISTINCT Name) FROM STUDENT;
1239 1338
1240 1339 ### Aliases for columns ### Aliases for columns
1241 1340
1242 ~~~{.sql}
1341 ~~~{.sqlmysql}
1342 SELECT Login FROM PROF;
1343 +---------+
1344 | Login |
1345 +---------+
1346 | aturing |
1347 | caubert |
1348 | bgates |
1349 | perdos |
1350 +---------+
1351
1243 1352 SELECT Login AS Username FROM PROF; SELECT Login AS Username FROM PROF;
1353 +----------+
1354 | Username |
1355 +----------+
1356 | aturing |
1357 | caubert |
1358 | bgates |
1359 | perdos |
1360 +----------+
1244 1361 ~~~ ~~~
1245 1362
1246 1363 ## Three-Valued Logic ## Three-Valued Logic
1247 1364
1248 Cf. [@Textbook6,5.1.1]
1365 Cf. [@Textbook6, 5.1.1], [@Textbook7, 7.1.1]
1249 1366
1250 1367 ### Meaning of `NULL` ### Meaning of `NULL`
1251 1368
1252 1369 `NULL` is `NULL` is
1253 1370
1254 1. Unknown Value
1255 2. Unavailable / Withheld
1256 3. Not Applicable
1371 1. Unknown value ("What is the date of birth of Jack the Ripper", "Is P = NP?")
1372 2. Unavailable / Withheld ("What is the number of english spies in France", "What is the identity of the Tiananmen Square Guy")
1373 3. Not Applicable ("What is the US SSN of a french person?", "What is the email address of an author of the XIXth century?")
1257 1374
1258 1375 ### Comparison with unknown values ### Comparison with unknown values
1259 1376
1260 If `NULL` is involved in a comparison, the result evaluates to "Unknown".
1377 If `NULL` is involved in a comparison, the result evaluates to "**U**nknown".
1261 1378
1262 1379 |||| ||||
1263 1380 :--: | :--: | :--: | :--: :--: | :--: | :--: | :--:
 
... ... For nested queries, cf. [@Textbook6, 5.1.2].
1292 1409
1293 1410 ### Select-project-join (4.3.1) ### Select-project-join (4.3.1)
1294 1411
1295 ~~~{.sql}
1296 SELECT Login FROM PROF, DEPARTMENT WHERE DEPARTMENT.Name = 'Mathematics' AND Department = Code;
1412 ~~~{.sqlmysql}
1413 SELECT Login FROM PROF, DEPARTMENT
1414 WHERE DEPARTMENT.Name = 'Mathematics'
1415 AND Department = Code;
1297 1416 ~~~ ~~~
1298 1417
1299 1418 - `Department.Name = 'Mathematics'` is the selection condition - `Department.Name = 'Mathematics'` is the selection condition
 
... ... SELECT Login FROM PROF, DEPARTMENT WHERE DEPARTMENT.Name = 'Mathematics' AND Dep
1301 1420 - Why do we use the fully qualified Name attribute for `Name`? - Why do we use the fully qualified Name attribute for `Name`?
1302 1421 - We have to list all the tables we want to consult, even if we use fully qualified names. - We have to list all the tables we want to consult, even if we use fully qualified names.
1303 1422
1304 ~~~{.sql}
1305 SELECT Name FROM STUDENT, GRADE WHERE Grade > 3.0 AND STUDENT.Login = GRADE.Login;
1423 ~~~{.sqlmysql}
1424 SELECT Name FROM STUDENT, GRADE
1425 WHERE Grade > 3.0
1426 AND STUDENT.Login = GRADE.Login;
1306 1427 ~~~ ~~~
1307 1428
1308 1429 - `Grade > 3.0` is the selection condition - `Grade > 3.0` is the selection condition
 
... ... SELECT Name FROM STUDENT, GRADE WHERE Grade > 3.0 AND STUDENT.Login = GRADE.Logi
1310 1431
1311 1432 We can have two join conditions! We can have two join conditions!
1312 1433
1313 ~~~{.sql}
1314 SELECT PROF.Name FROM PROF, DEPARTMENT, STUDENT WHERE STUDENT.Name = 'Ava Alyx' AND STUDENT.Major = DEPARTMENT.Code AND DEPARTMENT.Head = PROF.Login;
1434 ~~~{.sqlmysql}
1435 SELECT PROF.Name FROM PROF, DEPARTMENT, STUDENT
1436 WHERE STUDENT.Name = 'Ava Alyx'
1437 AND STUDENT.Major = DEPARTMENT.Code
1438 AND DEPARTMENT.Head = PROF.Login;
1315 1439 ~~~ ~~~
1316 1440
1317 1441 ### Aliasing tuples ### Aliasing tuples
1318 1442
1319 ~~~{.sql}
1320 SELECT A.Name FROM PROF AS A, DEPARTMENT, STUDENT AS B WHERE B.Name = 'Ava Alyx' AND B.Major = DEPARTMENT.Code AND DEPARTMENT.Head = A.Login;
1443 ~~~{.sqlmysql}
1444 SELECT A.Name FROM PROF AS A, DEPARTMENT, STUDENT AS B
1445 WHERE B.Name = 'Ava Alyx'
1446 AND B.Major = DEPARTMENT.Code
1447 AND DEPARTMENT.Head = A.Login;
1321 1448 ~~~ ~~~
1322 1449
1323 ~~~{.sql}
1324 SELECT Others.Login FROM GRADE AS Mine, GRADE AS Others WHERE Mine.Login = 'aalyx' and Mine.Grade < Others.Grade;
1450 ~~~{.sqlmysql}
1451 SELECT Others.Login FROM GRADE AS Mine, GRADE AS Others
1452 WHERE Mine.Login = 'aalyx'
1453 AND Mine.Grade < Others.Grade;
1325 1454 ~~~ ~~~
1326 1455
1327 1456 --- ---
1328 1457
1329 ~~~{.sql}
1458 ~~~{.sqlmysql}
1330 1459 SELECT Fellow.Name AS 'Fellow of Ava' SELECT Fellow.Name AS 'Fellow of Ava'
1331 1460 FROM STUDENT AS Me, STUDENT AS Fellow FROM STUDENT AS Me, STUDENT AS Fellow
1332 WHERE Me.Name = 'Ava Alyx' AND Fellow.Major = Me.Major AND NOT Fellow.Name = 'Ava Alyx';
1461 WHERE Me.Name = 'Ava Alyx'
1462 AND Fellow.Major = Me.Major
1463 AND NOT Fellow.Name = 'Ava Alyx';
1333 1464 ~~~ ~~~
1334 1465
1335 1466 ### Nested queries ### Nested queries
1336 1467
1337 ~~~{.sql}
1468 ~~~{.sqlmysql}
1338 1469 SELECT Login FROM GRADE WHERE Grade > SELECT Login FROM GRADE WHERE Grade >
1339 1470 (SELECT AVG(Grade) FROM GRADE); (SELECT AVG(Grade) FROM GRADE);
1340 1471 ~~~ ~~~
 
... ... SELECT Login FROM GRADE WHERE Grade >
1342 1473 Outer query, inner query. Outer query, inner query.
1343 1474 (Average of all non NULL values.) (Average of all non NULL values.)
1344 1475
1345 ~~~{.sql}
1476 ~~~{.sqlmysql}
1346 1477 SELECT Login FROM GRADE WHERE Grade >= ALL (SELECT Grade FROM GRADE WHERE Grade IS NOT NULL); SELECT Login FROM GRADE WHERE Grade >= ALL (SELECT Grade FROM GRADE WHERE Grade IS NOT NULL);
1347 1478
1348 1479 SELECT Login SELECT Login
 
... ... WHERE DEPARTMENT IN ( SELECT Major
1357 1488
1358 1489 ### Select-project-join (4.3.1) ### Select-project-join (4.3.1)
1359 1490
1360 ~~~{.sql}
1491 ~~~{.sqlmysql}
1361 1492 SELECT Login FROM PROF, DEPARTMENT WHERE DEPARTMENT.Name = 'Mathematics' AND Department = Code; SELECT Login FROM PROF, DEPARTMENT WHERE DEPARTMENT.Name = 'Mathematics' AND Department = Code;
1362 1493 ~~~ ~~~
1363 1494
 
... ... SELECT Login FROM PROF, DEPARTMENT WHERE DEPARTMENT.Name = 'Mathematics' AND Dep
1365 1496 - `Department = Code` is the join condition, because it combines two tuples. - `Department = Code` is the join condition, because it combines two tuples.
1366 1497 - Why do we use the fully qualified Name attribute for `Name`? - Why do we use the fully qualified Name attribute for `Name`?
1367 1498
1368 ~~~{.sql}
1499 ~~~{.sqlmysql}
1369 1500 SELECT Name FROM STUDENT, GRADE WHERE Grade > 3.0 AND STUDENT.Login = GRADE.Login; SELECT Name FROM STUDENT, GRADE WHERE Grade > 3.0 AND STUDENT.Login = GRADE.Login;
1370 1501 ~~~ ~~~
1371 1502
 
... ... SELECT Name FROM STUDENT, GRADE WHERE Grade > 3.0 AND STUDENT.Login = GRADE.Logi
1374 1505
1375 1506 We can have two join conditions! We can have two join conditions!
1376 1507
1377 ~~~{.sql}
1508 ~~~{.sqlmysql}
1378 1509 SELECT PROF.Name FROM PROF, DEPARTMENT, STUDENT WHERE STUDENT.Name = 'Ava Alyx' AND STUDENT.Major = DEPARTMENT.Code AND DEPARTMENT.Head = PROF.Login; SELECT PROF.Name FROM PROF, DEPARTMENT, STUDENT WHERE STUDENT.Name = 'Ava Alyx' AND STUDENT.Major = DEPARTMENT.Code AND DEPARTMENT.Head = PROF.Login;
1379 1510 ~~~ ~~~
1380 1511
1381 1512 ### Aliasing Tuples ### Aliasing Tuples
1382 1513
1383 ~~~{.sql}
1514 ~~~{.sqlmysql}
1384 1515 SELECT A.Name FROM PROF AS A, DEPARTMENT, STUDENT AS B WHERE B.Name = 'Ava Alyx' AND B.Major = DEPARTMENT.Code AND DEPARTMENT.Head = A.Login; SELECT A.Name FROM PROF AS A, DEPARTMENT, STUDENT AS B WHERE B.Name = 'Ava Alyx' AND B.Major = DEPARTMENT.Code AND DEPARTMENT.Head = A.Login;
1385 1516 ~~~ ~~~
1386 1517
1387 ~~~{.sql}
1518 ~~~{.sqlmysql}
1388 1519 SELECT Others.Login FROM GRADE AS Mine, GRADE as Others WHERE Mine.Login = 'aalyx' and Mine.Grade < Others.Grade; SELECT Others.Login FROM GRADE AS Mine, GRADE as Others WHERE Mine.Login = 'aalyx' and Mine.Grade < Others.Grade;
1389 1520 ~~~ ~~~
1390 1521
1391 ~~~{.sql}
1522 ~~~{.sqlmysql}
1392 1523 SELECT Fellow.Name AS 'Fellow of Ava' SELECT Fellow.Name AS 'Fellow of Ava'
1393 1524 FROM STUDENT AS Me, STUDENT AS Fellow FROM STUDENT AS Me, STUDENT AS Fellow
1394 1525 WHERE Me.Name = 'Ava Alyx' AND Fellow.Major = Me.Major AND NOT Fellow.Name = 'Ava Alyx'; WHERE Me.Name = 'Ava Alyx' AND Fellow.Major = Me.Major AND NOT Fellow.Name = 'Ava Alyx';
 
... ... WHERE Me.Name = 'Ava Alyx' AND Fellow.Major = Me.Major AND NOT Fellow.Name = 'Av
1396 1527
1397 1528 ### Nested Queries ### Nested Queries
1398 1529
1399 ~~~{.sql}
1530 ~~~{.sqlmysql}
1400 1531 SELECT Login FROM GRADE WHERE Grade > SELECT Login FROM GRADE WHERE Grade >
1401 1532 (SELECT AVG(Grade) FROM GRADE); (SELECT AVG(Grade) FROM GRADE);
1402 1533 ~~~ ~~~
 
... ... SELECT Login FROM GRADE WHERE Grade >
1404 1535 Outer query, inner query. Outer query, inner query.
1405 1536 (Average of all non NULL values.) (Average of all non NULL values.)
1406 1537
1407 ~~~{.sql}
1538 ~~~{.sqlmysql}
1408 1539 SELECT Login FROM GRADE WHERE Grade >= ALL (SELECT Grade FROM GRADE WHERE Grade IS NOT NULL); SELECT Login FROM GRADE WHERE Grade >= ALL (SELECT Grade FROM GRADE WHERE Grade IS NOT NULL);
1409 1540
1410 1541 SELECT Login SELECT Login
 
... ... Solution +.#
1857 1988
1858 1989 ## Problems ## Problems
1859 1990
1860 ### Setting up MySQL
1991 ### Setting up MySQL {#sec:gettingstartedwithmysql}
1861 1992
1862 1993 Problem -.+.#installation Problem -.+.#installation
1863 1994
1864 1995 In this problem, you will install the [MySQL](https://www.mysql.com/) DataBase Managment System and set it up. In this problem, you will install the [MySQL](https://www.mysql.com/) DataBase Managment System and set it up.
1865 1996 On top of being open source and free, it is one of the most widespread and used DBMS, as well as one of the most well-documented. On top of being open source and free, it is one of the most widespread and used DBMS, as well as one of the most well-documented.
1866 Linux users will use its community-developed fork, \href{https://mariadb.org/}{MariaDB}, but that won't make a difference in this course (up to [what's mentioned in this section](#differenceMySQLMariaDB)).
1997 Linux users will use its community-developed fork, \href{https://mariadb.org/}{MariaDB}, but that won't make a difference in this course (up to some minor aspects).
1867 1998
1868 1999 **bogue: cross ref?** **bogue: cross ref?**
1869 2000
File notes/img/rel_mod/BOOK_Exo.tex changed (mode: 100644) (index b55cedd..442f27f)
7 7 % BOOK(ISSN, AuthorRef, Title) % BOOK(ISSN, AuthorRef, Title)
8 8 % GAINED-AWARD(Ref, Name, BookISSN, Year) % GAINED-AWARD(Ref, Name, BookISSN, Year)
9 9
10 \Frame(0,0){1}[AUTHOR]{
11 Ref/A ,
12 Name/A ,
13 Address/A %
14 };
10 \Frame(0,0){1}[AUTHOR]{
11 Ref/A,
12 Name/A,
13 Address/A};
15 14
16 \Frame(0,-2.5){2}[BOOK]{
17 ISSN/A ,
18 AuthorRef/A ,
19 Title/A %
20 };
15 \Frame(0,-2.5){2}[BOOK]{
16 ISSN/A,
17 AuthorRef/A,
18 Title/A};
21 19
22 20 \Frame(0,-5){3}[GAINED-AWARD]{ \Frame(0,-5){3}[GAINED-AWARD]{
23 Ref/A ,
24 Name/A ,
25 BookISSN/A ,
26 Year/A %
27 };
21 Ref/A,
22 Name/A,
23 BookISSN/A,
24 Year/A};
28 25 \end{tikzpicture} \end{tikzpicture}
29 26 \end{document} \end{document}
File notes/img/rel_mod/BOOK_Sol.tex changed (mode: 100644) (index b63ac83..06e1598)
7 7 % BOOK(ISSN (PK), AuthorRef (FK to AUTHOR.REF), Title) % BOOK(ISSN (PK), AuthorRef (FK to AUTHOR.REF), Title)
8 8 % GAINED-AWARD(Ref (PK), Name, BookISSN (FK to BOOK.ISSN), Year) % GAINED-AWARD(Ref (PK), Name, BookISSN (FK to BOOK.ISSN), Year)
9 9
10 \Frame(0,0){1}[AUTHOR]{%first frame identified as 1 named PKLOYEE
11 Ref/PK ,% see that it is necessary to add a space
12 Name/A ,
13 Address/A %
14 };
10 \Frame(0,0){1}[AUTHOR]{
11 Ref/PK,
12 Name/A,
13 Address/A};
15 14
16 15 \Frame(0,-2.5){2}[BOOK]{ \Frame(0,-2.5){2}[BOOK]{
17 ISSN/PK ,
18 AuthorRef/A ,
19 Title/A %
20 };
16 ISSN/PK,
17 AuthorRef/A,
18 Title/A};
21 19
22 20 \Frame(0,-5){3}[GAINED-AWARD]{ \Frame(0,-5){3}[GAINED-AWARD]{
23 Ref/PK ,
24 Name/A ,
25 BookISSN/A ,
26 Year/A %
27 };
21 Ref/PK,
22 Name/A,
23 BookISSN/A,
24 Year/A};
28 25
29 26 \draw[FK] % From AuthorRef2 to Ref1 \draw[FK] % From AuthorRef2 to Ref1
30 27 (Ref1)++(0.1,0) -- ++(0,-.55) -- ++(4.5,0) coordinate (inter) (Ref1)++(0.1,0) -- ++(0,-.55) -- ++(4.5,0) coordinate (inter)
31 28 -- (AuthorRef2 -| inter) -- ++(0,-0.4) coordinate (inter) -- (AuthorRef2 -| inter) -- ++(0,-0.4) coordinate (inter)
32 -- (AuthorRef2 |- inter) --++(0,0.4);
29 -- (AuthorRef2 |- inter) --++(0,0.5);
33 30
34 31 \draw[FK] % From BookISSN3 to ISSN2 \draw[FK] % From BookISSN3 to ISSN2
35 32 (ISSN2)++(0.1,0) -- ++(0,-.55) -- ++(-1.1,0) coordinate (inter) (ISSN2)++(0.1,0) -- ++(0,-.55) -- ++(-1.1,0) coordinate (inter)
36 33 -- (BookISSN3 -| inter) -- ++(0,-0.4) coordinate (inter) -- (BookISSN3 -| inter) -- ++(0,-0.4) coordinate (inter)
37 -- (BookISSN3 |- inter) --++(0,0.4);
34 -- (BookISSN3 |- inter) --++(0,0.5);
38 35
39 36 \end{tikzpicture} \end{tikzpicture}
40 37 \end{document} \end{document}
File notes/img/rel_mod/CAR.tex changed (mode: 100644) (index 1ba0b81..7816693)
10 10 % PRICE(Stock-number (PK), Car-Vin (FK to CAR.VIN), Price, Margin) % PRICE(Stock-number (PK), Car-Vin (FK to CAR.VIN), Price, Margin)
11 11
12 12 \Frame(0,0){1}[CAR]{ \Frame(0,0){1}[CAR]{
13 VIN/PK ,
14 Make/A ,
15 Model/A ,
16 Year/A %
17 };
13 VIN/PK,
14 Make/A,
15 Model/A,
16 Year/A};
18 17
19 18 \Frame(0,-2.5){2}[DRIVER]{ \Frame(0,-2.5){2}[DRIVER]{
20 State/PK ,
21 Licence-Num/PK ,
22 Name/A ,
23 Address/A %
24 };
19 State/PK,
20 Licence-Num/PK,
21 Name/A,
22 Address/A};
25 23
26 24 \Frame(0,-5){3}[INSURANCE]{ \Frame(0,-5){3}[INSURANCE]{
27 Policy-Num/PK ,
28 Insured-Car/A ,
29 Insured-Driver-State/A ,
30 Insured-Driver-Licence-Num/A ,
31 Rate/A %
32 };
25 Policy-Num/PK,
26 Insured-Car/A,
27 Insured-Driver-State/A,
28 Insured-Driver-Licence-Num/A,
29 Rate/A};
33 30
34 31 \Frame(0,-7.5){4}[PRICE]{ \Frame(0,-7.5){4}[PRICE]{
35 Car-VIN/A ,
36 Price/A ,
37 Margin/A ,
38 Stock-Num/PK %
39 };
32 Car-VIN/A,
33 Price/A,
34 Margin/A,
35 Stock-Num/PK};
40 36
41 37
42 38 \draw[FK] % From Insured-Car3 to VIN1 \draw[FK] % From Insured-Car3 to VIN1
 
50 46 -- (Car-VIN4 |- inter) --++(0,0.5); -- (Car-VIN4 |- inter) --++(0,0.5);
51 47
52 48 \draw[FK] % From Insured-Driver-State3 to State2 \draw[FK] % From Insured-Driver-State3 to State2
53 (State2) -- ++(0,-.55) coordinate (inter) -- (Insured-Driver-State3 |- inter) --++(0,-1.2);
49 (State2) -- ++(0,-.7) coordinate (inter) -- (Insured-Driver-State3 |- inter) --++(0,-1.1);
54 50
55 51 \draw[FK] % From Insured-Driver-Licence-Num3 to Licence-Num2 \draw[FK] % From Insured-Driver-Licence-Num3 to Licence-Num2
56 (Licence-Num2) -- ++(0,-.45) coordinate (inter) -- (Insured-Driver-Licence-Num3 |- inter) --++(0,-1.3);
52 (Licence-Num2) -- ++(0,-.5) coordinate (inter) -- (Insured-Driver-Licence-Num3 |- inter) --++(0,-1.3);
57 53
58 54 \end{tikzpicture} \end{tikzpicture}
59 55 \end{document} \end{document}
File notes/img/rel_mod/CINEMA.tex changed (mode: 100644) (index 7f62651..79225b1)
11 11 %SHOWTIME(Id (PK), MovieId (FK to MOVIE.Id), AuditoriumId (FK to AUDITORIUM.Id), StartTime) %SHOWTIME(Id (PK), MovieId (FK to MOVIE.Id), AuditoriumId (FK to AUDITORIUM.Id), StartTime)
12 12 %TICKETS(Id (PK), ShowTimeId (FK to SHOWTIME.Id), Price) %TICKETS(Id (PK), ShowTimeId (FK to SHOWTIME.Id), Price)
13 13
14 \Frame(0,0){1}[STAR]{%first frame identified as 1 named PKLOYEE
15 Id/PK ,% see that it is necessary to add a space
16 Name/A ,
17 BirthDate/A
18 };
14 \Frame(0,0){1}[STAR]{
15 Id/PK,
16 Name/A,
17 BirthDate/A};
19 18
20 19 \Frame(0,-2.5){2}[MOVIE]{ \Frame(0,-2.5){2}[MOVIE]{
21 Id/PK ,
22 Title/A ,
23 Year/A ,
24 Length/A ,
25 Genre/A
26 };
20 Id/PK,
21 Title/A,
22 Year/A,
23 Length/A,
24 Genre/A};
27 25
28 26 \Frame(0,-5){3}[FEATURE-IN]{ \Frame(0,-5){3}[FEATURE-IN]{
29 StarId/PK ,
30 MovieId/PK
31 };
27 StarId/PK,
28 MovieId/PK};
32 29
33 30 \Frame(8,0){4}[THEATER]{ \Frame(8,0){4}[THEATER]{
34 Id/PK ,
35 Name/A ,
36 Address/A
37 };
31 Id/PK,
32 Name/A,
33 Address/A};
38 34
39 35 \Frame(8,-2.5){5}[AUDITORIUM]{ \Frame(8,-2.5){5}[AUDITORIUM]{
40 Id/PK ,
41 Capacity/A ,
42 Theater/A
43 };
36 Id/PK,
37 Capacity/A,
38 Theater/A};
44 39
45 40 \Frame(8,-5){6}[SHOWTIME]{ \Frame(8,-5){6}[SHOWTIME]{
46 Id/PK ,
47 MovieId/A ,
48 AuditoriumId/A ,
49 StartTime/A
50 };
41 Id/PK,
42 MovieId/A,
43 AuditoriumId/A,
44 StartTime/A};
51 45
52 46
53 47 \Frame(8,-7.5){7}[TICKET]{ \Frame(8,-7.5){7}[TICKET]{
54 Id/PK ,
55 ShowTimeId/A ,
56 Price/A
57 };
48 Id/PK,
49 ShowTimeId/A,
50 Price/A};
58 51
59 52 \draw[FK] % From StarId3 to Id1 \draw[FK] % From StarId3 to Id1
60 53 (Id1)++(0.1,0) -- ++(0,-.55) -- ++(-1.1,0) coordinate (inter) (Id1)++(0.1,0) -- ++(0,-.55) -- ++(-1.1,0) coordinate (inter)
61 54 -- (StarId3 -| inter) -- ++(0,-0.4) coordinate (inter) -- (StarId3 -| inter) -- ++(0,-0.4) coordinate (inter)
62 -- (StarId3 |- inter) --++(0,0.4);
55 -- (StarId3 |- inter) --++(0, 0.4);
63 56
64 57 \draw[FK] % From MovieId3 to Id2 \draw[FK] % From MovieId3 to Id2
65 (Id2)++(-0.1,0) -- ++(0,-.55) -- ++(-.7,0) coordinate (inter)
66 -- (MovieId3 -| inter) -- ++(0,-0.2) coordinate (inter)
67 -- (MovieId3 |- inter) --++(0,0.2);
58 (Id2)++(-0.1,0) -- ++(0,-.75) -- ++(3,0) coordinate (inter)
59 -- (MovieId3 -| inter) -- ++(0,-0.4) coordinate (inter)
60 -- (MovieId3 |- inter) --++(0,0.4);
68 61
69 62 \draw[FK] % From Theater5 to Id4 \draw[FK] % From Theater5 to Id4
70 (Id4)++(0.1,0) -- ++(0,-.55) -- ++(4,0) coordinate (inter)
63 (Id4)++(0.1,0) -- ++(0,-.55) -- ++(3.5,0) coordinate (inter)
71 64 -- (Theater5 -| inter) -- ++(0,-0.2) coordinate (inter) -- (Theater5 -| inter) -- ++(0,-0.2) coordinate (inter)
72 -- (Theater5 |- inter) --++(0,0.2);
65 -- (Theater5 |- inter) --++(0,0.3);
73 66
74 67 \draw[FK] % From MovieId6 to Id2 \draw[FK] % From MovieId6 to Id2
75 (Id2)++(0.1,0) -- ++(0,-.55) -- ++(4,0) coordinate (inter)
68 (Id2)++(0.1,0) -- ++(0,-.55) -- ++(3.2,0) coordinate (inter)
76 69 -- (MovieId6 -| inter) -- ++(0,-0.4) coordinate (inter) -- (MovieId6 -| inter) -- ++(0,-0.4) coordinate (inter)
77 -- (MovieId6 |- inter) --++(0,0.4);
70 -- (MovieId6 |- inter) --++(0,0.5);
78 71
79 72 \draw[FK] % From AuditoriumId6 to Id5 \draw[FK] % From AuditoriumId6 to Id5
80 (Id5)++(0.1,0) -- ++(0,-.55) -- ++(6.5,0) coordinate (inter)
73 (Id5)++(0.1,0) -- ++(0,-.55) -- ++(6,0) coordinate (inter)
81 74 -- (AuditoriumId6 -| inter) -- ++(0,-0.2) coordinate (inter) -- (AuditoriumId6 -| inter) -- ++(0,-0.2) coordinate (inter)
82 -- (AuditoriumId6 |- inter) --++(0,0.2);
75 -- (AuditoriumId6 |- inter) --++(0,0.3);
83 76
84 77
85 78 \draw[FK] % From ShowTimeId7 to Id6 \draw[FK] % From ShowTimeId7 to Id6
86 (Id6)++(0.1,0) -- ++(0,-.55) -- ++(-.7,0) coordinate (inter)
79 (Id6)++(0.1,0) -- ++(0,-.8) -- ++(-.7,0) coordinate (inter)
87 80 -- (ShowTimeId7 -| inter) -- ++(0,-0.2) coordinate (inter) -- (ShowTimeId7 -| inter) -- ++(0,-0.2) coordinate (inter)
88 -- (ShowTimeId7 |- inter) --++(0,0.2);
81 -- (ShowTimeId7 |- inter) --++(0,0.3);
89 82
90 83 \end{tikzpicture} \end{tikzpicture}
91 84 \end{document} \end{document}
File notes/img/rel_mod/EMPLOYEE.tex changed (mode: 100644) (index ee2077e..95f42ac)
4 4 \input{template.tex} \input{template.tex}
5 5
6 6 \Frame(0,0){1}[PKLOYEE]{ \Frame(0,0){1}[PKLOYEE]{
7 Fname/A ,
8 Minit/A ,
9 Lname/A ,
10 Ssn/PK ,
11 Bdate/A ,
12 Address/A ,
13 Sex/A ,
14 Salary/A ,
15 Super-Ssn/A ,
16 Dno/A %
17 };
7 Fname/A,
8 Minit/A,
9 Lname/A,
10 Ssn/PK,
11 Bdate/A,
12 Address/A,
13 Sex/A,
14 Salary/A,
15 Super-Ssn/A,
16 Dno/A};
18 17
19 18 \Frame(0,-2.5){2}[DEPARTMENT]{ \Frame(0,-2.5){2}[DEPARTMENT]{
20 Dname/A ,
21 Dnumber/PK ,
22 Mgr-ssn/A ,
23 Mgr-Start-date/A %
24 };
19 Dname/A,
20 Dnumber/PK,
21 Mgr-ssn/A,
22 Mgr-Start-date/A};
25 23
26 24 \Frame(0,-5){3}[DEPT-LOCATIONS]{ \Frame(0,-5){3}[DEPT-LOCATIONS]{
27 Dnumber/PK ,
28 Dlocations/PK %
29 };
25 Dnumber/PK,
26 Dlocations/PK};
30 27
31 28 \Frame(0,-7.5){4}[PROJECT]{ \Frame(0,-7.5){4}[PROJECT]{
32 Pname/A ,
33 Pnumber/PK ,
34 Plocation/A ,
35 Dnum/A %
36 };
29 Pname/A,
30 Pnumber/PK,
31 Plocation/A,
32 Dnum/A};
37 33
38 34 \Frame(0,-10){5}[WORKS ON]{ \Frame(0,-10){5}[WORKS ON]{
39 Essn/PK ,
40 Pno/PK ,
41 Hours/A %
42 };
35 Essn/PK,
36 Pno/PK,
37 Hours/A};
43 38
44 39 \Frame(0,-12.5){6}[DEPENDENT]{ \Frame(0,-12.5){6}[DEPENDENT]{
45 Essn/PK ,
46 Dependent-Name/A ,
47 Sex/A ,
48 Bdate/A ,
49 Relationship/A %
50 };
40 Essn/PK,
41 Dependent-Name/A,
42 Sex/A,
43 Bdate/A,
44 Relationship/A};
51 45
52 46 \draw[FK] % From Essn6 to Ssn1 \draw[FK] % From Essn6 to Ssn1
53 47 (Ssn1)++(0.1,0) -- ++(0,-.55) -- ++(4.5,0) coordinate (inter) %inter is the name of coordinate register (Ssn1)++(0.1,0) -- ++(0,-.55) -- ++(4.5,0) coordinate (inter) %inter is the name of coordinate register
File notes/img/rel_mod/PROF_DEPARTMENT.tex added (mode: 100644) (index 0000000..db12557)
1 % !TeX document-id = {9fd243f0-f0ae-45f7-9f88-fa9555c363d3}
2 % !TeX TXS-program:compile = txs:///xelatex/[--shell-escape]
3 \documentclass[convert={outfile=\jobname.svg},border=20pt]{standalone}
4 \input{template.tex}
5
6 % PROF(Login (PK), Name, Department (FK to DEPARTMENT.Code))
7 % DEPARTMENT(Code (PK), Name, Head (FK to PROF.Login))
8
9 \Frame(0,0){1}[PROF]{
10 Login/PK,
11 Name/A,
12 Department/A};
13
14 \Frame(5, 0){2}[DEPARTMENT]{
15 Code/PK,
16 Name/A,
17 Head/A};
18
19 \draw[FK] % From Department1 to Code2
20 (Code2)++(0.1,0) -- ++(0,-.5) -- ++(-1,0) coordinate (inter)
21 -- (Department1 |- inter) --++(0,0.6);
22
23 \draw[FK] % From Head2 to Login1
24 (Login1)++(0.1,0) -- ++(0,-1) coordinate (inter)
25 -- (Head2 |- inter) --++(0, 1.1);
26
27 \end{tikzpicture}
28 \end{document}
File notes/img/rel_mod/TRAIN_Exo.tex changed (mode: 100644) (index 9c31541..f5b43a2)
8 8 % ASSIGNED-TO(TrainRef (PK, FK to TRAIN.REF), ConductorID (PK, FK to CONDUCTOR.CompanyID), Date (PK)) % ASSIGNED-TO(TrainRef (PK, FK to TRAIN.REF), ConductorID (PK, FK to CONDUCTOR.CompanyID), Date (PK))
9 9
10 10 \Frame(0,0){1}[TRAIN]{ \Frame(0,0){1}[TRAIN]{
11 Ref/PK ,
12 Model/A ,
13 Year/A %
14 };
11 Ref/PK,
12 Model/A,
13 Year/A};
15 14
16 15 \Frame(0,-2.5){2}[CONDUCTOR]{ \Frame(0,-2.5){2}[CONDUCTOR]{
17 CompanyID/PK ,
18 Name/A ,
19 ExperienceLevel/A %
20 };
16 CompanyID/PK,
17 Name/A,
18 ExperienceLevel/A};
21 19
22 20 \Frame(0,-5){3}[ASSIGNED-TO]{ \Frame(0,-5){3}[ASSIGNED-TO]{
23 TrainRef/PK ,
24 ConductorID/PK ,
25 Date/PK %
26 };
21 TrainRef/PK,
22 ConductorID/PK,
23 Date/PK};
27 24
28 25 \draw[FK] % From TrainRef3 to Ref1 \draw[FK] % From TrainRef3 to Ref1
29 26 (Ref1)++(0.1,0) -- ++(0,-.55) -- ++(-1,0) coordinate (inter) (Ref1)++(0.1,0) -- ++(0,-.55) -- ++(-1,0) coordinate (inter)
File notes/img/rel_mod/template.tex changed (mode: 100644) (index d8a28f5..f4ca1d8)
1 \renewcommand\familydefault{\sfdefault} % Default family: serif
1 2 \usepackage[usenames,dvipsnames]{xcolor} \usepackage[usenames,dvipsnames]{xcolor}
2 3 \usepackage{tikz} \usepackage{tikz}
4 \usepackage{soul}
3 5 \usetikzlibrary{calc} \usetikzlibrary{calc}
4 6 \usetikzlibrary{arrows, decorations.markings,positioning,backgrounds,shapes} \usetikzlibrary{arrows, decorations.markings,positioning,backgrounds,shapes}
5 7 \definecolor{WIRE}{HTML}{002FA7} % Klein Blue \definecolor{WIRE}{HTML}{002FA7} % Klein Blue
6 \newbox\ubox %Used to define new node property
8 \usepackage{ulem}
9 \renewcommand{\ULdepth}{3pt}
10
11 \newcommand\whiteuline{\bgroup\markoverwith
12 {\textcolor{white}{\rule[-0.5ex]{2pt}{0.4pt}}}\ULon}
7 13
8 14 \tikzset{FK/.style={thick,<-,thick,>=latex}} \tikzset{FK/.style={thick,<-,thick,>=latex}}
9 15
16 \newbox\ubox
10 17 \begin{document} \begin{document}
11 \begin{tikzpicture}[
12 PK node/.style={% Style for empatized boxes
13 rectangle, line width =1pt,
14 anchor=west,
15 underline, % new property
16 align=center,
18 \begin{tikzpicture}[
19 PK/.style={% Style for empatized boxes
20 rectangle, line width =1pt,
21 anchor=west,
22 underline, % new property
23 align=center,
17 24 text=white, text=white,
18 minimum height=.8cm,
19 fill=WIRE!60,
20 draw=black,
21 },
22 A node/.style={% Style for normal boxes.
23 rectangle, line width =1pt,
24 anchor=west,
25 align=left,
26 minimum height=.6cm,
25 minimum height=.8cm,
26 text height=1.5ex,
27 text depth=.25ex,
28 fill=WIRE!50,
29 draw=black,
30 },
31 A/.style={% Style for normal boxes.
32 rectangle,
33 line width =1pt,
34 anchor=west,
35 align=left,
36 minimum height=.6cm,
37 text height=1.5ex,
38 text depth=.25ex,
27 39 fill=WIRE!10, fill=WIRE!10,
28 draw=black,
29 },
30 underline/.append style={% define new style property
31 execute at begin node={%
32 \setbox\ubox=\hbox\bgroup
33 },
34 execute at end node={%
35 \egroup\underline{\box\ubox}%
36 }
37 },
38 ] % Uff that is all the configuration for tickzpicture xD
39
40 % Define an brute force objet "Frame"
41 % Variables 1:Position, 2: Identifier, 3: Title of frame 4: Subframe/Boxtype
42 \def\Frame(#1)#2[#3]#4{%
43 \begin{scope}[shift={(#1)}]
44 \node[font=\bf, anchor=west] (Title) at (-0.2,0.7) {#3};
45 \edef\k{0}% Variable for box positión
46 \edef\x{0}% Variable for named coordinate centering - below box
47 \foreach \id/\style in {#4} {%enter sub frame data Name/Boxtype ,Name2/Boxtype | An space before Boxtype is needed
48 \node[\style node] (h) at (\k pt,0) {\id}; % % Draw a node depending on the variables.
49 \pgfmathparse{\k+0.5*width{"\id"}+3.4pt} % Uses the textwidth to calculate named coordinate
50 \xdef\x{\pgfmathresult} % The resul is saved in the variable \x
51 \draw (\x pt,-0.4) coordinate (\id#2); %Create a named coordinate concatenated: "sub frame data Name"+"identifier"
52 \pgfmathparse{\k+width{"\id"}+6.8pt}% Calculate positión for each subframe box.
53 \xdef\k{\pgfmathresult}% Save the value to be added to the next iteration value.
54 }
55 \end{scope}
56 }% disadvantages: Is not posible to use Frame data Name like: Name_another_desc instead I use Name-another-desc
40 draw=black,
41 inner ysep=5pt
42 },
43 underline/.append style={% define new style property
44 execute at begin node={%
45 \setbox\ubox=\hbox\bgroup
46 },
47 execute at end node={%
48 \egroup\whiteuline{\box\ubox}%
49 }
50 },
51 ] % Uff that is all the configuration for tickzpicture xD
52
53 % Define an brute force objet "Frame"
54 % Variables 1:Position, 2: Identifier, 3: Title of frame 4: Subframe/Boxtype
55 \def\Frame(#1)#2[#3]#4{%
56 \begin{scope}[shift={(#1)}]
57 \node[font=\bf, anchor=west] (Title) at (-0.2,0.7) {#3};
58 \edef\k{0}% Variable for box positión
59 \edef\x{0}% Variable for named coordinate centering - below box
60 \foreach \id/\style in {#4} {%enter sub frame data Name/Boxtype ,Name2/Boxtype | An space before Boxtype is needed
61 \node[\style] (h) at (\k pt,0) {\id}; % % Draw a node depending on the variables.
62 \pgfmathparse{\k+0.5*width{"\id"}+3.4pt} % Uses the textwidth to calculate named coordinate
63 \xdef\x{\pgfmathresult} % The resul is saved in the variable \x
64 \draw (\x pt,-0.4) coordinate (\id#2); %Create a named coordinate concatenated: "sub frame data Name"+"identifier"
65 \pgfmathparse{\k+width{"\id"}+6.8pt}% Calculate positión for each subframe box.
66 \xdef\k{\pgfmathresult}% Save the value to be added to the next iteration value.
67 }
68 \end{scope}
69 }% disadvantages: Is not posible to use Frame data Name like: Name_another_desc instead I use Name-another-desc
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/caubert/CSCI_3410

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/caubert/CSCI_3410

Clone this repository using git:
git clone git://git.rocketgit.com/user/caubert/CSCI_3410

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main