e-jambon bio photo

e-jambon

Ce qui se conçoit bien s'exprime clairement.

Email Twitter

Ce post n’a pas beaucoup d’intérêt pour le lecteur de ce blog.

C’est toujours dans la suite de mes révisions sur odin-project.

Ce sont des notes.

Notez quand même qu’Odin-Project vous permet d’aborder quand même pas mal de choses. C’est un curriculum complet.

PARTIE I : Learn SQL the hard way

Reading notes. Taking those notes in french - CRUD create read update delete

Choix d’une base de donnée

Choix du bouquin : SQLLite.

Mes choix : - PostgreSQL, pour un déploiement en production, multiutilisateurs. Robuste et beaucoup plus puissant que SQLite. Coût de maintenance élevé. Attention à ne pas en faire un “choix par défaut”, c’est carrément surdimensionné pour la plupart des applications, et ça risque de peser sur les performances si ce n’est pas pour répondre à un besoin.Très répandu. Nécessite un minimum d’expérience avec les bases de données.

  • MySQL, s’il s’agit uniquement d’un stockage de données, que le moteur n’est pas uilisé pour organiser les donnée, idéal. Robuste, moins puissant que PostgreSQL, mais nettement plus riche que SQLite et surtout, offre une gestion multi-utilisateur. L’idéal pour commencer sur Rails. Très très répandu parmi les hébergeurs.

  • SQLite pour le test et le développement, les données perso. Aucune gestion utilisateur / faible coût de maintenance.

SQLite se télécharge ici

IDEE : Tant que j’y suis, ajouter un objet dans ma librairie “link” pour enregistrer les liens dans une base sqlite. Ca me permettra de faire quelques tests et de permettre de stocker les liens dans leur propre table / base sans passer par active record. Pour se faire j’utiliserai la gem “sqlite3”, qui permet de s’interfacer avec sqlite3.

Au passage, j’en profite pour lire la doc de sqlite3

Exercice 0 : The setup

shell-prompt$ sqlite3 test.db #if it does not exist, creates the db  
sqlite>  create table test(id)

On crée la base de donnée directement dans le shell, avec la première commande, et on s’y connecte Puis une fois connecté à ladite base, on crée un table “test” dedans.

La doc de Sqlite3 se trouve ici

Exercice 1 : Création des tables

In the Link case, this is how I proceed :

1
2
3
4
5
6
CREATE TABLE link(
    id INTEGER PRIMARY KEY,
    title TEXT,
    description TEXT,
    url TEXT
);

Exercice 2 : Création de multiple tables dans la base

Une base peut contenir plusieurs tables. Par exemple, dans la base link, je peux créer la table link_status comme suit :

1
2
3
4
5
6
7
CREATE TABLE linkStatus (
    id INTEGER PRIMARY KEY,
    valid NUMERIC,              /* is a boolean. 0 stands for false, 1 stands for true */
    last_code INTEGER,          /* contains the last code the server provided for the url */
    num_error_check INTEGER,    /* How many times the url was checked with an error response */
    last_checked NUMERIC        /* is a date */
);

Note : Sqlite3 ne gère que le types de donnés suivants :

  • INTEGER
  • TEXT
  • NUMERIC
  • REAL
  • NONE

This is how they relate to sql types

  • INTEGER => INT, INTEGER, TINYINT, SMALLINT, MEDIUMINT, BIGINT, UNSIGNED BIG INT, INT2, INT8
  • TEXT => CHARACTER(20), VARCHAR(255), VARYING CHARACTER(255), NCHAR(55), NATIVE CHARACTER(70),NVARCHAR(100), TEXT, CLOB
  • NONE => BLOB
  • REAL => REAL, DOUBLE, DOUBLE PRECISION, FLOAT
  • NUMERIC => NUMERIC, DATE, DATETYPE, BOOLEAN

Exercice 3 : Ajout de données dans une table

Ajout = INSERT Si je veux créer des données par défaut dans ma table, je vais utiliser l’instruction “INSERT” comme suit :

1
2
3
4
5
6
7
8
INSERT INTO link (id,
                title,
                description,url
                )
        VALUES( 0,
                "Les liens d'E-Jambon",
                "Un site avec tous les liens vraiment utiles que je ne veux pas perdre",
                "http://links.e-jambon.com");
  • INSERT -> Ajouter
  • INTO -> dedans
  • link ()-> La liste des champs dans lequel je veux écrire dans la table link, dans l’ordre dans lequel je vais donner les valeurs.
  • VALUES() ->La liste des valeurs à insérer dans les champs, dans l’ordre précisé précédemment

Donner un statut à ce lien:

1
2
INSERT INTO linkStatus( id,valid,last_code, num_error_check,last_checked )
       VALUES(0,1,200,0,645781000);

( pour la date, théoriquement le nombre de sécondes écoulées depuis 1970, pas encore vérifié )

Exercice 4 : Ajout de données référentielles

Il n’y a aucun lien pour l’instant entre les données de la table link et link_status. Or j’aimerai bien pouvoir retrouver le linkStatus à partir d’un link donné. Pour ça, je vais créer une table “link_linkStatus”

1
2
3
4
CREATE TABLE link_linkStatus (
    link_id INTEGER,
    linkStatus_id INTEGER
    );

et insérer un enregistrement qui indique le lien entre les deux.

1
INSERT INTO link_linkStatus (link_id, linkStatus_id) VALUES (0,0);

Exécutons tout ces petits scripts :

sqlite3 -echo link.db < ./creation/*.sql
sqlite3 -echo link.db < ./insert/*.sql

Exercice 5: retrouver des données.

La syntaxe de la requête de base est simple :

1
2
3
SELECT <NOMS_DE_CHAMPS>
FROM <NOMS_DES_TABLES>
WHERE <CONDITIONS_SUR_LES_ENREGISTREMENTS>

`

Exercice 6 : Selectionner au travers de plusieurs tables

Quand on utilise plusieurs tables dans le “FROM” d’une requête, il convient de préfixer le nom des champ par le nom de la table à laquelle il appartient :

1
2
3
SELECT link.id, linkStatus.id, link.title, link.url, link.description, linkStatus.valid, link_linkStatus.link_id, link_linkStatus.linkStatus_id
FROM link, linkStatus, link_linkStatus
WHERE linkStatus.id = link_linkStatus.linkStatus_id AND link.id = link_linkStatus.link_id ;

Exercice 7 : Suppression de données

Voilà la syntaxe :

1
2
3
DELETE
FROM <NOM_TABLE>
WHERE <CONDITION_POUR_SELECTIONNER_LES_ENREGISTREMENTS_A_SUPPRIMER>

`

Exercice 8 : Modification de données en utilisant une requête sur des tables liées. Par exemple si je veux supprimer tous les status de liens qui n’existent plus :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DELETE FROM pet WHERE id IN (
    SELECT pet.id
    FROM pet, person_pet, person
    WHERE
    person.id = person_pet.person_id AND
    pet.id = person_pet.pet_id AND
    person.first_name = "Zed"
);

SELECT * FROM pet;
SELECT * FROM person_pet;

DELETE FROM person_pet
    WHERE pet_id NOT IN (
        SELECT id FROM pet
    );

SELECT * FROM person_pet;

Exercice 9 : Mettre à jour des données

La syntaxe :

1
2
3
    UPDATE <TABLE_NAME>
    SET <NOM_DE_CHAMP = VALEUR,...>
    WHERE <CONDITIONS...>

En général, on connaît l’ID que l’on veut changer, mais on peut aussi faire des modifications par lots, donc sur toute la table résultante. On peut également utiliser des sous requête pour la conditions.

Exercice 10 :Mettre à jour des donnes complexes

Exemple :

1
2
3
4
5
6
7
8
9
10
SELECT * FROM pet;
UPDATE pet SET name = "Zed's Pet" WHERE id IN (
    SELECT pet.id
    FROM pet, person_pet, person
    WHERE
    person.id = person_pet.person_id AND
    pet.id = person_pet.pet_id AND
    person.first_name = "Zed"
);
SELECT * FROM pet;

Exercice 11 : Remplacer des données

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* This should fail because 0 is already taken. */
INSERT INTO person (id, first_name, last_name, age)
    VALUES (0, 'Frank', 'Smith', 100);

/* We can force it by doing an INSERT OR REPLACE. */
INSERT OR REPLACE INTO person (id, first_name, last_name, age)
    VALUES (0, 'Frank', 'Smith', 100);

SELECT * FROM person;

/* And shorthand for that is just REPLACE. */
REPLACE INTO person (id, first_name, last_name, age)
    VALUES (0, 'Zed', 'Shaw', 37);

/* Now you can see I'm back. */
SELECT * FROM person;

Exercice 12 : Detruire / altérer des tables

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* Only drop table if it exists. TRES UTILE QUAND ON SCRIPT UNE BASE DE DONNEE */
DROP TABLE IF EXISTS person;

/* Create again to work with it. */
CREATE TABLE person (
    id INTEGER PRIMARY KEY,
    first_name TEXT,
    last_name TEXT,
    age INTEGER
);

/* Rename the table to peoples. */
ALTER TABLE person RENAME TO peoples;

/* Add a hatred column to peoples. MIGRATIONS, tu m'entends ? */
ALTER TABLE peoples ADD COLUMN hatred INTEGER;

/* Rename peoples back to person. */
ALTER TABLE peoples RENAME TO person;

.schema person

/* We don't need that. */
DROP TABLE person;

`

Exercice 13 : Travaux pratiques

Schéma du départ :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE person (
    id INTEGER PRIMARY KEY,
    first_name TEXT,
    last_name TEXT,
    age INTEGER
);
CREATE TABLE person_pet (
    person_id INTEGER,
    pet_id INTEGER
);
CREATE TABLE pet (
    id INTEGER PRIMARY KEY,
    name TEXT,
    breed TEXT,
    age INTEGER,
    dead INTEGER,
    dob DATETIME
);

Schéma à obtenir :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 CREATE TABLE person (
    id INTEGER PRIMARY KEY,
    first_name TEXT,
    last_name TEXT,
    age INTEGER,
    dead INTEGER,
    phone_number TEXT,
    salary FLOAT,
    dob DATETIME);
CREATE TABLE person_pet (
    person_id INTEGER,
    pet_id INTEGER,
    purchased_on DATETIME);
CREATE TABLE pet (
    id INTEGER PRIMARY KEY,
    name TEXT,
    breed TEXT,
    age INTEGER,
    dead INTEGER,
    parent INTEGER);

Exercice 14 : Les transactions

Ah enfin, on commence à jouer. * BEGIN * COMMIT * ROLLBACK

au passage, on peut lire un ficher avec la commande .read et voir le schéma à n’importe quel moment avec la commande .schema La command ROLLBACK permet de revenir à l’état qui précède le début de la transaction (avant le BEGIN, donc). La commande COMMIT permet de terminer la transaction ET d’enregistrer le résultat.

Une bonne habitude quand on bosse sur une base de donnée c’est de toujours travailler avec des transactions, et si on utilise un outil (genre toad sur Oracle), de bien s’assurer qu’il ne commit pas automatiquement après la lecture d’un script !!!

Exercice 15 : Modèle de données.

Petite lecture sur la conceptualisation d’un modèle de données. Rien de particulier, que du déjà connu pour moi. Ceci étant, vu les bases sur lesquelles dans lesquelles j’ai eu à mettre les pattes, y’en a des qui auraient bien fait de lire ça.

Exercice 16 :..

Ah bah le bouquin n’est pas terminé et s’arrête là… dommage, j’étais bien lancé. Ca faisait une bonne révision accelerée.

PARTIE II : Cours en ligne de stanford

XML data

Software

  • xmllint pour valider un document avec DTD & Schema

Pour valider un xml dont le dtd est dans le fichier lui même.

xmllint --valid --noout DataFileWithDTD.xml

Pour valider un xml dont le dtd se trouve dans son propre fichier

 xmllint --dtdvalid DTD.dtd --noout DataFileWithoutDTD.xml

Pour valider des données xml contre un schema qui se trouve dans son propre fichier :

xmllint --schema XMLSchemaFile.xsd --noout DataFile.xml

Et là, c’est le bug : ils utilisent Kernow, un logiciel propriétaire. Donc j’ai cherché quelques minutes des solutions open-source pour manipuler du xml et faire du xpath/xquery. Voici les solutions à retenir à ce jour :

  • Cocoon => Java
  • XBase => Java
  • Saxon => Java + propriétaire…
  • Exist => Java
  • XQilla => C/C++ library & utilitaire en ligne de commande. AH enfin.
  • Zorba => C/C++ , librairie avec des interfaces multiples, très à jour, open source. Interfaces pour C++/C, C#, PHP,Java, XQJ, Python, Ruby … Miam… sauf que ça a l’air un chouilla complexe à utiliser sous Windows/OS-X. Pas de bol, je suis en ce moment sous OS-X. N’empêche que ça reste ce que j’ai vu de mieux.

Bref, y’a plein de solutions pour java => Je refuse de me forcer à plonger là dedans si c’est pas impératif. Y’a d’autrs solutions, mais alors c’est soit linux, soit un bel effort d’intégration à faire. Là, je révise, c’est pas le moment.

  • Un tableau comparatif des technos sur wikipedia

  • Reste nokogiri, avec Ruby pour parser du xml, mais bon… c’était pas vraiment le sujet.

Je suis en pleine révision, mais j’ai pas mis java dans ma liste. Je regarde la vidéo, je passe à la suite.

NoSQL XML XQuery/XPath, ce que j’en retiens

En ce qui me concerne et contrairement à ce que j’ai pu voir/lire un peu partout, la mode “noSQL” avec du xml derrière, à ce jour, c’est une option qui en quelques dizaines de minutes de recherche me semble toujours aussi complexe. En tout cas nettement plus que le SQL.

A utiliser par exemple si votre application sort vraiment des clous : c’est pas un CRUD pur et simple. Par exemple si l’un des besoins majeur de votre application est d’exporter les données dans des documents aux formats ésotériques (genre transformer les données en vidéos, en slides lisibles par la librairie javascript XYZ), c’est probablement un bon choix. Quoique ça sera peut être aussi simple de faire générer un export xml par une base de donnée relationnelle, puis de faire la transformation dans la foulée en utilisant du xslt.

A voir, mais ne pas sous-estimer le coût de cette solution en matière de complexité.

JSON data

JSON = notation simple, auto-descriptive, relativement bien adapatée à la programmation. D’où son succès. Il y a des solutions à surveiller pour utiliser JSON :

  • Apache Drill + Hadoop
  • CoucheDB , qui semble être beaucoup utilisée, en particulier pour les web-apps, en particuliers celles qui se distribuent sur les smartphone ou pour connecter les “objets” à internet.

L’intérêt principal c’est la facilité d’adaptabilité du système à la demande. Le deuxième, c’est la flexibilité (comme en xml). Enin, la possibilité d’avoir des bases “personnelles” déportées sur des terminaux relativement légers (genre smartphone). Bref, c’est très utile pour les “webapps”.

Pour le schema, on utilise JSON schema. Ca m’a l’air plutôt simple au premier abord. Et puis y’a de quoi valider dans tout plein de langages.

  • Ruby :
  • Javascript : on s’y attend, il y en a plusieurs, très actifs. En même temps, c’est plutôt logique.
  • Java : Etrangement, le monde java c’est xml, et pas JSON. Donc il y a un et un seul outil recensé.
  • Python : idem, plein de projets. je les note pas, j’utilise pas assez python pour que ça puisse m’interresser dans l’immédiat.
  • C++ : assez pauvre. En même temps, on sait pourquoi : on fait moins de web en C++ qu’ailleurs, on a moins besoin de valider du JSON.

Bref, c’est un vrai domaine a explorer à la fin de mes révisions.

A regarder :