0
L’envers du décor
24 Octobre 2013
Apiness SA
Laurent Kohler

&

Nicolas Marfurt

www.apiness-software.ch
Le décor
Echange de données

Services Web
Echange de données

Services Web
Back-end Web
Gestion du contenu de l’application
(data model «business»)
Multilingue
Multi-utilisateurs
Gestion des autori...
Application mobile
Outil d’affichage de données
Fonctionne également hors ligne
Structure et design simple
Synchronisation d...
Effort de développement
Effort de développement
Effort de développement
Situation «typique»
Un client demande «une petite application
mobile multi-plateformes»
➡ aspect visuel et fonctionnel
➡ m...
L’envers du décor
Options

Web server & Web services
Persistance données côté client mobile
- Modèle objet (Core Data)
- Modèle relationnel ...
Contexte: back-end
Projet d’exemple Audio Guide

LAMP
CMS Joomla
Données «structurées», modèle relationnel
(MySQL)
Contexte: application iOS
Projet d’exemple Audio Guide

Modèle relationnel
Correspond au type de modèle du back-end

SQLit...
Modèle de données

Modèle «server» != modèle «app»
Exemples :

•

Serveur
-

•

Données multilingue
Gestion des autorisati...
Au travail !
iOS - Cocoa
Options d’accès à SQLite
Options d’accès à SQLite
•

Utilisation de Core Data
Options d’accès à SQLite
•

Utilisation de Core Data
Options d’accès à SQLite
•

Utilisation de Core Data

•

Utilisation directe de la libraire SQLite native
➡

Fonctions C
Options d’accès à SQLite
•

Utilisation de Core Data

•

Utilisation directe de la libraire SQLite native
➡

•

Fonctions ...
Options d’accès à SQLite
•

Utilisation de Core Data

•

Utilisation directe de la libraire SQLite native
➡

•

Wrapper ou...
Options d’accès à SQLite
•

Utilisation de Core Data

•

Utilisation directe de la libraire SQLite native
➡

•

Wrapper ou...
Architecture

APSSQLite
APSSQLiteObjectCoding
protocol

APSSQLiteDatabaseController

APSSQLiteDatabase

APSSQLiteRequest

...
Architecture

APSSQLite
APSSQLiteObjectCoding
protocol

APSSQLiteDatabaseController

APSSQLiteDatabase

APSSQLiteRequest

...
Architecture
MyProjectDatabaseController

APSSQLite
APSSQLiteObjectCoding
protocol

APSSQLiteDatabaseController

APSSQLite...
Architecture
MyProjectDatabaseController

APSSQLite
APSSQLiteObjectCoding
protocol

APSSQLiteDatabaseController

APSSQLite...
Architecture
MyProjectDatabaseController

MyClassResultSet

APSSQLiteDatabaseController

APSSQLiteObjectCoding
protocol

A...
Architecture
MyProjectDatabaseController

MyClassResultSet

APSSQLiteDatabaseController

APSSQLiteObjectCoding
protocol

A...
Architecture
MyProjectDatabaseController

MyClassResultSet

MyClass

APSSQLiteDatabaseController

APSSQLiteObjectCoding
pr...
Intégration
Modèle

MyClassResultSet

MyViewController
MyClass

MyProjectDatabaseController

Contrôleur

APSSQLite
Demo
Appel SQLite
APSSQLiteDatabase
- (BOOL)executeCUDRequest:(APSSQLiteRequest *)request error:(NSError *__autoreleasing *)err...
Appel SQLite
APSSQLiteDatabase
- (BOOL)executeCUDRequest:(APSSQLiteRequest *)request error:(NSError *__autoreleasing *)err...
Exécution d’une requête
TopicResultSet : APSSQLiteResultSet

+ (TopicResultSet *)fetchAll {
__block TopicResultSet *result...
Exécution d’une requête
TopicResultSet : APSSQLiteResultSet

+ (TopicResultSet *)fetchAll {
__block TopicResultSet *result...
Affichage des données
MyViewController : UITableViewController
@interface TopicListViewController ()
@property (strong, non...
Affichage des données
MyViewController : UITableViewController
@interface TopicListViewController ()
@property (strong, non...
Affichage des données
MyViewController : UITableViewController
@interface TopicListViewController ()
@property (strong, non...
Base de données
Scénarios d’évolution des données

•

Mises à jour fréquentes mais en petit volume (news)
➡ Intégralité des données pas né...
Contexte
Projet d’exemple Audio Guide

•

Installation de contenu type «audio guide musée»
- Texte, images, audio
- Créati...
Approches

•
•
•
•

Option 1 : «naïve» (la plus simple)
Option 2 : «typique SQLite» (transaction)
Option 3 : «insertion en...
Contexte
2 tables relativement petites
- table parent : 12 colonnes (int, float, varchar)
- table détail : 7 colonnes (int,...
Option 1
Insertion ligne par ligne

FOR EACH ROW
EXEC:INSERT INTO TBL
(c1,c2...) SELECT 123,
‘abc’,...
Option 1
Insertion ligne par ligne

insertions /
sec

FOR EACH ROW
EXEC:INSERT INTO TBL
(c1,c2...) SELECT 123,
‘abc’,...
Option 1
Insertion ligne par ligne

insertions /
sec

FOR EACH ROW
EXEC:INSERT INTO TBL
(c1,c2...) SELECT 123,
‘abc’,...

...
Option 2
Insertion ligne par ligne…
dans une transaction
BEGIN TRANSACTION
FOR EACH ROW
EXEC:INSERT INTO TBL
(c1,c2...) SE...
Option 2
Insertion ligne par ligne…
dans une transaction
BEGIN TRANSACTION
insertions /
sec

FOR EACH ROW
EXEC:INSERT INTO...
Option 2
Insertion ligne par ligne…
dans une transaction
BEGIN TRANSACTION
insertions /
sec

FOR EACH ROW
EXEC:INSERT INTO...
Option 3
Insertion de plusieurs lignes en
une commande insert
EXEC:
INSERT
VALUES
(123,
,(345,
,(678,

INTO TBL (c1,c2)
‘S...
Option 3
Insertion de plusieurs lignes en
une commande insert

SQLite ne connait pas insert many values !
(dépend des vers...
Option 3 - syntaxe SQLite
Insertion de plusieurs lignes en
une commande insert
EXEC:
INSERT INTO TBL (c1,c2)
SELECT 123, ‘...
Option 3 - syntaxe SQLite
Insertion de plusieurs lignes en
une commande insert

Limite SQLite :
au maximum 500 union selec...
Option 3 - syntaxe SQLite
Insertion par paquets de 500
lignes
FOR EACH ROW
BUILD INSERT STATEMENT
WHEN «ENOUGH»
EXEC:
INSE...
Option 3 - syntaxe SQLite
Insertion par paquets de 500
lignes

Code un peu plus
complexe

FOR EACH ROW
BUILD INSERT STATEM...
Option 4
Insertion par paquets de 500
lignes…
dans une transaction
BEGIN TRANSACTION
FOR EACH ROW
BUILD INSERT STATEMENT
W...
Option 4
Insertion par paquets de 500
lignes…
dans une transaction

Insertion «rapide»
de nombreuses lignes

BEGIN TRANSAC...
Comparaison des 4 options

insertions /
sec
Comparaison des 4 options

insertions /
sec

Option 4 45x plus rapide que l’option 1
1500 insertions / seconde sur iPad 3
...
Option 4
Insertion par paquets de 500
lignes…
dans une transaction

Performance satisfaisante dans le contexte
Au prix d’u...
Insert et Update
•

•

Coder «if exists update else insert»

•
•

Long à développer, long à exécuter
Update forcément itér...
Insert et Replace
•
•

Parfait pour des données provenant à 100% du serveur
Attention si certaines colonnes sont maintenue...
Insert et Replace - exemple
EXEC:
INSERT INTO news (newsId, newsTitle,newsDesc, hasBeenRead)
SELECT
123
,‘SoftShake 2013’
...
Insert et Replace - exemple
EXEC:
INSERT INTO news (newsId, newsTitle,newsDesc, hasBeenRead)
SELECT
123
,‘SoftShake 2013’
...
Insert et Replace - commentaires
•
•

Lorsque certaines colonnes sont maintenues localement
Data model :
- une table pour ...
Delete
•

Côté serveur
- «soft delete» (flag data inactive)

•

Côté application
- delete physique (à la fin de la synchroni...
Réorganisation DB

•
•

SQLite est comparable aux autres base de données
Après de nombreux insert/update/delete, besoin de...
Quand réorganiser ?
•
•
•

A l’ancienne; «une fois par semaine» ?
Souvent; après chaque synchro ?
Lorsque jugé nécessaire ...
Quand réorganiser ?
•
•
•

A l’ancienne; «une fois par semaine» ?
Souvent; après chaque synchro ?
Lorsque jugé nécessaire ...
Options SQLite
•
•

Journal mode

•

Mode «delete» par défaut

Attention au mode Write Ahead Log (WAL)

•
•

Meilleure con...
Pour conclure
•
•

SQLite est excellent et très performant !

•

Utiliser EXPLAIN pour analyser ce que fait SQLite

En défi...
Merci à vous tous pour votre attention !
No
SQL
?
Core Data ?

SQLite ?

Back-end
Web?

Discussion
BACKUP SLIDES
Backend web - gestion des données
Backend web - gestion des données
Outils existants (connus)

•

Contraintes par rapport au data model

•

(Très) rapide po...
Gestion des données - nos choix
•

•

«middle-tier» commun qui génère le html en fonction de
paramètres et accès aux donné...
Core Data - iOS 7 - Sqlite
•

Version SQLite

•
•

•

•

- iOS 6: version 3.7.13
- iOS 7.0: version 3.7.13

Options Core D...
Softshake 2013 Apiness SA l'envers du décor
Softshake 2013 Apiness SA l'envers du décor
Softshake 2013 Apiness SA l'envers du décor
Upcoming SlideShare
Loading in...5
×

Softshake 2013 Apiness SA l'envers du décor

35

Published on

Pour une fois, il s’agit de parler de ce que l’on ne montre pas toujours au public : «l’envers du décor», soit le backend base de données et la synchronisation avec l’application iPhone.

Le but de la session est de présenter notre expérience dans le contexte suivant :

Base de données locale Sqlite
Base de données serveur MySql
Synchronisation des données application - serveur


Présentation de l’application
Présentation de l’administration des données (écrans de maintenance des données intégrés à Joomla)
Présentation de l’approche et du code, productivité de développement pour le backend web
Sqlite sans CoreData
Echange des données en JSON
Procédures stockées et vues MySql
Discussion concernant les techniques possibles et la productivité

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
35
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Softshake 2013 Apiness SA l'envers du décor"

  1. 1. L’envers du décor 24 Octobre 2013
  2. 2. Apiness SA Laurent Kohler & Nicolas Marfurt www.apiness-software.ch
  3. 3. Le décor
  4. 4. Echange de données Services Web
  5. 5. Echange de données Services Web
  6. 6. Back-end Web Gestion du contenu de l’application (data model «business») Multilingue Multi-utilisateurs Gestion des autorisations - par fonction - sur la donnée • • • Web services de synchronisation
  7. 7. Application mobile Outil d’affichage de données Fonctionne également hors ligne Structure et design simple Synchronisation des données - robuste - performante
  8. 8. Effort de développement
  9. 9. Effort de développement
  10. 10. Effort de développement
  11. 11. Situation «typique» Un client demande «une petite application mobile multi-plateformes» ➡ aspect visuel et fonctionnel ➡ mais aussi développement important : - back-end Web - synchronisation
  12. 12. L’envers du décor
  13. 13. Options Web server & Web services Persistance données côté client mobile - Modèle objet (Core Data) - Modèle relationnel (SQLite natif) - Autre (XML, JSON, plist...)
  14. 14. Contexte: back-end Projet d’exemple Audio Guide LAMP CMS Joomla Données «structurées», modèle relationnel (MySQL)
  15. 15. Contexte: application iOS Projet d’exemple Audio Guide Modèle relationnel Correspond au type de modèle du back-end SQLite (sans Core Data) Optimisation du SQL et des paramètres db
  16. 16. Modèle de données Modèle «server» != modèle «app» Exemples : • Serveur - • Données multilingue Gestion des autorisations Application - Une langue sélectionnée
  17. 17. Au travail !
  18. 18. iOS - Cocoa
  19. 19. Options d’accès à SQLite
  20. 20. Options d’accès à SQLite • Utilisation de Core Data
  21. 21. Options d’accès à SQLite • Utilisation de Core Data
  22. 22. Options d’accès à SQLite • Utilisation de Core Data • Utilisation directe de la libraire SQLite native ➡ Fonctions C
  23. 23. Options d’accès à SQLite • Utilisation de Core Data • Utilisation directe de la libraire SQLite native ➡ • Fonctions C Wrapper ou framework existant ➡ FMDB
  24. 24. Options d’accès à SQLite • Utilisation de Core Data • Utilisation directe de la libraire SQLite native ➡ • Wrapper ou framework existant ➡ • Fonctions C FMDB Wrapper «maison»
  25. 25. Options d’accès à SQLite • Utilisation de Core Data • Utilisation directe de la libraire SQLite native ➡ • Wrapper ou framework existant ➡ • Fonctions C FMDB Wrapper «maison» - raison historique, plaisir d’explorer mainmise sur le code (tests)
  26. 26. Architecture APSSQLite APSSQLiteObjectCoding protocol APSSQLiteDatabaseController APSSQLiteDatabase APSSQLiteRequest SQLite APSSQLiteObjectPersisting protocol APSSQLiteResultSet
  27. 27. Architecture APSSQLite APSSQLiteObjectCoding protocol APSSQLiteDatabaseController APSSQLiteDatabase APSSQLiteRequest SQLite APSSQLiteObjectPersisting protocol APSSQLiteResultSet
  28. 28. Architecture MyProjectDatabaseController APSSQLite APSSQLiteObjectCoding protocol APSSQLiteDatabaseController APSSQLiteDatabase APSSQLiteRequest SQLite APSSQLiteObjectPersisting protocol APSSQLiteResultSet
  29. 29. Architecture MyProjectDatabaseController APSSQLite APSSQLiteObjectCoding protocol APSSQLiteDatabaseController APSSQLiteDatabase APSSQLiteRequest SQLite APSSQLiteObjectPersisting protocol APSSQLiteResultSet
  30. 30. Architecture MyProjectDatabaseController MyClassResultSet APSSQLiteDatabaseController APSSQLiteObjectCoding protocol APSSQLite APSSQLiteDatabase APSSQLiteRequest SQLite APSSQLiteObjectPersisting protocol APSSQLiteResultSet
  31. 31. Architecture MyProjectDatabaseController MyClassResultSet APSSQLiteDatabaseController APSSQLiteObjectCoding protocol APSSQLite APSSQLiteDatabase APSSQLiteRequest SQLite APSSQLiteObjectPersisting protocol APSSQLiteResultSet
  32. 32. Architecture MyProjectDatabaseController MyClassResultSet MyClass APSSQLiteDatabaseController APSSQLiteObjectCoding protocol APSSQLiteObjectPersisting protocol APSSQLite APSSQLiteDatabase APSSQLiteRequest SQLite APSSQLiteResultSet
  33. 33. Intégration Modèle MyClassResultSet MyViewController MyClass MyProjectDatabaseController Contrôleur APSSQLite
  34. 34. Demo
  35. 35. Appel SQLite APSSQLiteDatabase - (BOOL)executeCUDRequest:(APSSQLiteRequest *)request error:(NSError *__autoreleasing *)error { ! BOOL success = YES; ! sqlite3_stmt *statement; int rc = sqlite3_prepare(self.db, [request.query UTF8String], -1, &statement, NULL); ! if(rc == SQLITE_OK) { rc = sqlite3_step(statement); ! ! ! ! ! ! ! ! ! } else { *error = [[self class] errorWithCode:rc message:[NSString stringWithUTF8String:sqlite3_errmsg(self.db)]]; ! success = NO; } ! ! ! } if(rc != SQLITE_DONE) { *error = [[self class] errorWithCode:rc message:[NSString stringWithUTF8String:sqlite3_errmsg(self.db)]]; ! success = NO; } sqlite3_finalize(statement); return success;
  36. 36. Appel SQLite APSSQLiteDatabase - (BOOL)executeCUDRequest:(APSSQLiteRequest *)request error:(NSError *__autoreleasing *)error { ! BOOL success = YES; ! sqlite3_stmt *statement; int rc = sqlite3_prepare(self.db, [request.query UTF8String], -1, &statement, NULL); ! if(rc == SQLITE_OK) { rc = sqlite3_step(statement); ! ! ! ! ! ! ! ! ! } else { *error = [[self class] errorWithCode:rc message:[NSString stringWithUTF8String:sqlite3_errmsg(self.db)]]; ! success = NO; } ! ! ! } if(rc != SQLITE_DONE) { *error = [[self class] errorWithCode:rc message:[NSString stringWithUTF8String:sqlite3_errmsg(self.db)]]; ! success = NO; } sqlite3_finalize(statement); return success;
  37. 37. Exécution d’une requête TopicResultSet : APSSQLiteResultSet + (TopicResultSet *)fetchAll { __block TopicResultSet *resultSet = nil; [[GuideDatabaseController sharedDatabaseController] performBlockAndWait:^(APSSQLiteDatabase *database) { NSString *query = @"SELECT * FROM audio_topic t WHERE t.isPublished = 1 ORDER BY t.sequence"; APSSQLiteRequest *request = [APSSQLiteRequest requestWithQuery:query]; request.resultClass = [TopicResultSet class]; NSError *error = nil; resultSet = [database executeFetchRequest:request error:&error]; // Handle error... }]; return resultSet; }
  38. 38. Exécution d’une requête TopicResultSet : APSSQLiteResultSet + (TopicResultSet *)fetchAll { __block TopicResultSet *resultSet = nil; [[GuideDatabaseController sharedDatabaseController] performBlockAndWait:^(APSSQLiteDatabase *database) { NSString *query = @"SELECT * FROM audio_topic t WHERE t.isPublished = 1 ORDER BY t.sequence"; APSSQLiteRequest *request = [APSSQLiteRequest requestWithQuery:query]; request.resultClass = [TopicResultSet class]; }]; } NSError *error = nil; resultSet = [database executeFetchRequest:request error:&error]; // Handle error... return resultSet;
  39. 39. Affichage des données MyViewController : UITableViewController @interface TopicListViewController () @property (strong, nonatomic) TopicResultSet *topicResultSet; @end - (void)viewDidLoad { [super viewDidLoad]; } self.topicResultSet = [TopicResultSet fetchAll]; - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.topicResultSet count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { TopicTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TopicListViewControllerTopicCell]; NSDictionary *topic = self.topicResultSet[indexPath.row]; cell.textLabel.text = topic[TopicColumnTitle]; cell.detailTextLabel.text = topic[TopicColumnDescription]; } return cell;
  40. 40. Affichage des données MyViewController : UITableViewController @interface TopicListViewController () @property (strong, nonatomic) TopicResultSet *topicResultSet; @end - (void)viewDidLoad { [super viewDidLoad]; } self.topicResultSet = [TopicResultSet fetchAll]; - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.topicResultSet count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { TopicTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TopicListViewControllerTopicCell]; } return cell;
  41. 41. Affichage des données MyViewController : UITableViewController @interface TopicListViewController () @property (strong, nonatomic) TopicResultSet *topicResultSet; @end - (void)viewDidLoad { [super viewDidLoad]; } self.topicResultSet = [TopicResultSet fetchAll]; - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.topicResultSet count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { TopicTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TopicListViewControllerTopicCell]; Topic *topic = [self.topicResultSet topicForRowAtIndex:indexPath.row]; cell.textLabel.text = topic.title; cell.detailTextLabel.text = topic.topicDescription; } return cell;
  42. 42. Base de données
  43. 43. Scénarios d’évolution des données • Mises à jour fréquentes mais en petit volume (news) ➡ Intégralité des données pas nécessaire • • Mises à jour en masse (catalogue produit) Installation en masse, mises à jour de petit volume (audio guide)
  44. 44. Contexte Projet d’exemple Audio Guide • Installation de contenu type «audio guide musée» - Texte, images, audio - Création par volume de 100 à 1000 éléments environ - Mise à jour sporadique et en petite quantité
  45. 45. Approches • • • • Option 1 : «naïve» (la plus simple) Option 2 : «typique SQLite» (transaction) Option 3 : «insertion en masse» Option 4 : «insertion en masse» + transaction
  46. 46. Contexte 2 tables relativement petites - table parent : 12 colonnes (int, float, varchar) - table détail : 7 colonnes (int, varchar), foreign key parent Mesure - nombre d’insertions par seconde - données de référence : 1000 parents et 2000 détails
  47. 47. Option 1 Insertion ligne par ligne FOR EACH ROW EXEC:INSERT INTO TBL (c1,c2...) SELECT 123, ‘abc’,...
  48. 48. Option 1 Insertion ligne par ligne insertions / sec FOR EACH ROW EXEC:INSERT INTO TBL (c1,c2...) SELECT 123, ‘abc’,...
  49. 49. Option 1 Insertion ligne par ligne insertions / sec FOR EACH ROW EXEC:INSERT INTO TBL (c1,c2...) SELECT 123, ‘abc’,... Trop lent !
  50. 50. Option 2 Insertion ligne par ligne… dans une transaction BEGIN TRANSACTION FOR EACH ROW EXEC:INSERT INTO TBL (c1,c2...) SELECT 123, ‘abc’,... COMMIT (or rollback)
  51. 51. Option 2 Insertion ligne par ligne… dans une transaction BEGIN TRANSACTION insertions / sec FOR EACH ROW EXEC:INSERT INTO TBL (c1,c2...) SELECT 123, ‘abc’,... COMMIT (or rollback)
  52. 52. Option 2 Insertion ligne par ligne… dans une transaction BEGIN TRANSACTION insertions / sec FOR EACH ROW EXEC:INSERT INTO TBL (c1,c2...) SELECT 123, ‘abc’,... COMMIT (or rollback) 2.5x plus rapide !
  53. 53. Option 3 Insertion de plusieurs lignes en une commande insert EXEC: INSERT VALUES (123, ,(345, ,(678, INTO TBL (c1,c2) ‘Sqlite’) ‘Soft’) ‘Shake’);
  54. 54. Option 3 Insertion de plusieurs lignes en une commande insert SQLite ne connait pas insert many values ! (dépend des versions de SQLite…) EXEC: INSERT VALUES (123, ,(345, ,(678, INTO TBL (c1,c2) ‘Sqlite’) ‘Soft’) ‘Shake’);
  55. 55. Option 3 - syntaxe SQLite Insertion de plusieurs lignes en une commande insert EXEC: INSERT INTO TBL (c1,c2) SELECT 123, ‘Sqlite’ UNION SELECT 345, ‘Soft’ UNION SELECT 678, ‘Shake’;
  56. 56. Option 3 - syntaxe SQLite Insertion de plusieurs lignes en une commande insert Limite SQLite : au maximum 500 union select ! EXEC: INSERT INTO TBL (c1,c2) SELECT 123, ‘Sqlite’ UNION SELECT 345, ‘Soft’ UNION SELECT 678, ‘Shake’;
  57. 57. Option 3 - syntaxe SQLite Insertion par paquets de 500 lignes FOR EACH ROW BUILD INSERT STATEMENT WHEN «ENOUGH» EXEC: INSERT INTO TBL (c1,c2) SELECT 123, ‘Sqlite’ UNION SELECT 345, ‘Soft’ UNION SELECT 678, ‘Shake’;
  58. 58. Option 3 - syntaxe SQLite Insertion par paquets de 500 lignes Code un peu plus complexe FOR EACH ROW BUILD INSERT STATEMENT WHEN «ENOUGH» EXEC: INSERT INTO TBL (c1,c2) SELECT 123, ‘Sqlite’ UNION SELECT 345, ‘Soft’ UNION SELECT 678, ‘Shake’;
  59. 59. Option 4 Insertion par paquets de 500 lignes… dans une transaction BEGIN TRANSACTION FOR EACH ROW BUILD INSERT STATEMENT WHEN «ENOUGH» EXEC: INSERT INTO TBL (c1,c2) SELECT 123, ‘Sqlite’ UNION SELECT 345, ‘Soft’ UNION SELECT 678, ‘Shake’; COMMIT (or rollback)
  60. 60. Option 4 Insertion par paquets de 500 lignes… dans une transaction Insertion «rapide» de nombreuses lignes BEGIN TRANSACTION FOR EACH ROW BUILD INSERT STATEMENT WHEN «ENOUGH» EXEC: INSERT INTO TBL (c1,c2) SELECT 123, ‘Sqlite’ UNION SELECT 345, ‘Soft’ UNION SELECT 678, ‘Shake’; COMMIT (or rollback)
  61. 61. Comparaison des 4 options insertions / sec
  62. 62. Comparaison des 4 options insertions / sec Option 4 45x plus rapide que l’option 1 1500 insertions / seconde sur iPad 3 600 insertions / seconde sur iPhone 4
  63. 63. Option 4 Insertion par paquets de 500 lignes… dans une transaction Performance satisfaisante dans le contexte Au prix d’un code un peu plus complexe Optio adopt n ée ! BEGIN TRANSACTION FOR EACH ROW BUILD INSERT STATEMENT WHEN «ENOUGH» EXEC: INSERT INTO TBL (c1,c2) SELECT 123, ‘Sqlite’ UNION SELECT 345, ‘Soft’ UNION SELECT 678, ‘Shake’; COMMIT (or rollback)
  64. 64. Insert et Update • • Coder «if exists update else insert» • • Long à développer, long à exécuter Update forcément itératif avec SQLite (1 by 1) Approche SQLite efficace : INSERT OR REPLACE INTO... ➡ Si validation intégrité référentielle (foreign key) Différer le contrôle au moment du commit : PRAGMA defer_foreign_keys = ON Optio adopt n ée !
  65. 65. Insert et Replace • • Parfait pour des données provenant à 100% du serveur Attention si certaines colonnes sont maintenues localement ! • Le «insert or replace» modifie toutes les colonnes ➡ Option possible : Utiliser un sub-select pour obtenir la valeur locale
  66. 66. Insert et Replace - exemple EXEC: INSERT INTO news (newsId, newsTitle,newsDesc, hasBeenRead) SELECT 123 ,‘SoftShake 2013’ ,’24 et 25 octobre 2013’ ,(SELECT hasBeenRead FROM news WHERE newsId = 123) UNION SELECT ....
  67. 67. Insert et Replace - exemple EXEC: INSERT INTO news (newsId, newsTitle,newsDesc, hasBeenRead) SELECT 123 ,‘SoftShake 2013’ ,’24 et 25 octobre 2013’ ,(SELECT hasBeenRead FROM news WHERE newsId = 123) UNION SELECT .... work aroun d 30% p lus le ! nt.
  68. 68. Insert et Replace - commentaires • • Lorsque certaines colonnes sont maintenues localement Data model : - une table pour les données «serveur» - une table pour les données «locale» - une view pour accéder aux 2 facilement • • Pas de perte de performance Approche robuste Optio adopt n ée !
  69. 69. Delete • Côté serveur - «soft delete» (flag data inactive) • Côté application - delete physique (à la fin de la synchronisation)
  70. 70. Réorganisation DB • • SQLite est comparable aux autres base de données Après de nombreux insert/update/delete, besoin de : - Récupérer l’espace avec : VACUUM
  71. 71. Quand réorganiser ? • • • A l’ancienne; «une fois par semaine» ? Souvent; après chaque synchro ? Lorsque jugé nécessaire ? - Evaluer les pages vides avec PRAGMA freelist_count - Si «nombreuses» pages inutilisées : effectuer le «vacuum»
  72. 72. Quand réorganiser ? • • • A l’ancienne; «une fois par semaine» ? Souvent; après chaque synchro ? Lorsque jugé nécessaire ? - Evaluer les pages vides avec PRAGMA freelist_count - Si «nombreuses» pages inutilisées : effectuer le «vacuum» vacuum est assez rapide surtout s’il est effectué avant que la db soit totalement désorganisée Important de le faire, «peu importe» quand !
  73. 73. Options SQLite • • Journal mode • Mode «delete» par défaut Attention au mode Write Ahead Log (WAL) • • Meilleure concurrence d’accès Meilleure performance «maintenant»... - Car une partie du travail différée à plus tard ! - Sur device mobile, comportement potentiellement ennuyeux
  74. 74. Pour conclure • • SQLite est excellent et très performant ! • Utiliser EXPLAIN pour analyser ce que fait SQLite En définissant bien les indexes, pas de soucis de performance du côté des select
  75. 75. Merci à vous tous pour votre attention !
  76. 76. No SQL ? Core Data ? SQLite ? Back-end Web? Discussion
  77. 77. BACKUP SLIDES
  78. 78. Backend web - gestion des données
  79. 79. Backend web - gestion des données Outils existants (connus) • Contraintes par rapport au data model • (Très) rapide pour des fonctions simples • Risque d’atteindre une impasse Développement «sur mesure» • trop long, trop coûteux
  80. 80. Gestion des données - nos choix • • «middle-tier» commun qui génère le html en fonction de paramètres et accès aux données par procédures stockées • • • Code PHP stable, on génère/écrit seulement le sql Rapide Optimisation des stored procedures toujours possible Outil «maison» : JEdit • Développement par Apiness (Marc Perroulaz, L.Kohler)
  81. 81. Core Data - iOS 7 - Sqlite • Version SQLite • • • • - iOS 6: version 3.7.13 - iOS 7.0: version 3.7.13 Options Core Data • • Utilisation du mode WAL par défaut depuis iOS 7 Possibilité de passer des options SQLite à Core Data, entre autre le mode de journalisation: • @{ NSSQLitePragmasOption : @{@"journal_mode" : @"DELETE"} } Trace Core Data (iOS 7 / sans analyse) • • • • - pragma journal_mode=wal - pragma cache_size=200 - pragma page_count - pragma freelist_count
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×