web-dev-qa-db-fra.com

Plusieurs tables avec le même type d'objets dans la base de données de pièces

J'utilise Room comme base de données pour l'application. J'ai un scénario où une Object d'un certain type doit être stockée dans des tables séparées. Par exemple, prenons la Object appelée Book.Java 

Maintenant, je veux avoir deux tables SQL:

  • Livres_Lire
  • Books_To_Lire 

ignore toutes les conventions de nommage pour SQL DB s'il vous plaît - ceci est juste un exemple

Problème  

Normalement, on utilisera simplement @Entity(tableName = "Books_Read") dans la classe Book.Java et on aura une classe DAO qui utilisera ce nom de table. 

La chose est; Comment pourrais-je alors utiliser la même classe Book.Java pour la stocker dans la table Books_To_Read? Depuis que j'ai déjà défini @Entity(tableName = "Books_Read") dans la classe Book.Java et que je ne vois pas où définir la table Books_To_Read pour la classe Book.Java 

La seule solution que j'ai pu trouver, ce qui me semble un peu hackery et unnessasery, était de créer une nouvelle classe - appelons-la BookToRead.Java qui étend Book.Java et définisse @Entity(tableName = "Books_To_Read") dans la classe. 

Question

Y a-t-il une meilleure façon de faire ceci ou est-ce la manière attendue de le gérer? 

18
Robert J. Clegg

Est-ce la manière attendue de le gérer?

Non . C'est une mauvaise approche. Vous devriez éliminer la duplication de données pour plusieurs raisons.

  • Cela coûtera de l'espace de stockage. Au fur et à mesure que la taille de la base de données augmente, cela va devenir de plus en plus grave.

  • Cela compliquera le système. Si vous mettez à jour un seul champ , Vous devrez peut-être effectuer la même action à différents endroits . Si vous manquez l'un d'eux, les données complètes deviendront Incohérentes. Il est possible d'effectuer des opérations telles que Une seule transaction. Mais il est toujours préférable de garder la structure de la base de données Pure.


Solution

Méthode 1: Introduire de nouveaux tableaux

Vous pouvez stocker les détails des livres dans une seule table, par exemple, "Books". "Books_To_Read" ou toute autre table ne doit contenir que la référence à la table "Books" (en utilisant l'identifiant/la clé primaire dans la table "Books"). Vous pouvez ensuite utiliser le mot clé JOIN pour obtenir la totalité de l'enregistrement en une seule requête.

Cette méthode est recommandée si chaque type (livres lus et non lus dans ce cas) a son propre ensemble de champs (Comme le read_date, read_time pour les livres lus et wish_to_read pour les livres non lus).

Méthode 2: Introduire un nouveau champ

Vous pouvez simplement ajouter un nouveau type qui spécifie le type. Dans ce cas, il n'y a que deux types (lu et non lu), un champ booléen (quelque chose comme is_read) conviendra.

Ce serait la méthode la plus simple. Mais cela ne fonctionnera que si vous voulez simplement indiquer à quel type appartient la ligne. Si vous avez besoin de stocker des données de type spécifique et que vous introduisez des champs supplémentaires à cette fin, n'oubliez pas que ces champs existent également pour d'autres types.

11
Anees

Voici comment j'ai finalement résolu ce problème: 

J'ai ajouté un identifiant à la classe Book.Java qui indique s'il a été lu ou non. Soutenue par une EnumType qui était soit book_read ou book_unread, puis dans ma DAO pour "BooksDataTable", je n'utilisais alors qu'un SQL query à select la ID que je veux. Donc, en changeant la requête, je peux obtenir tous les books_read ou books_to_read ou all_books. De cette façon, il n'y a pas de duplication de données et tout est dans une table, sans avoir à utiliser les relations JOIN ou OneToMany

1
Robert J. Clegg
@OneToMany(mappedBy="book_id")
private Set<Book> book

Je pense que c'est le meilleur moyen de connecter deux tables. Essayez-le et laissez-moi savoir votre retour d'information. Je vais donner une autre solution

0
Muthu

J'étais en train d'écrire un exemple d'application quand Ahamad a donné sa réponse. 

Room fournit une couche d'abstraction sur SQLite pour permettre une utilisation fluide accès à la base de données tout en exploitant toute la puissance de SQLite.

l'idée principale est la même que celle de stocker les données du livre dans une table et d'utiliser l'identifiant du livre dans d'autres tables regardez mon exemple projet

résultat de logcat 

02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 1 name = Book 0, author Author 0}
02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 2 name = Book 1, author Author 1}
02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 3 name = Book 2, author Author 2}
02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 4 name = Book 3, author Author 3}
02-19 16:39:26.767 10520-10520/com.example.jingged.roomtest E/MainActivity: BookToRead Book{id = 3 name = Book 2, author Author 2}
02-19 16:39:26.767 10520-10520/com.example.jingged.roomtest E/MainActivity: BookToRead Book{id = 4 name = Book 3, author Author 3}
02-19 16:39:26.768 10520-10520/com.example.jingged.roomtest E/MainActivity: BooksRead Book{id = 1 name = Book 0, author Author 0}
02-19 16:39:26.768 10520-10520/com.example.jingged.roomtest E/MainActivity: BooksRead Book{id = 2 name = Book 1, author Author 1}
0
Sahil Manchanda