J'ai 2 tables avec des millions d'enregistrements:
Le premier tableau est Abonnement
et le deuxième tableau est Message
.
Dans le tableau Subscription
, j'ai 3 index:
subscription_id
msisdn
reporting_id
Cependant, dans la table Message
, je n'ai que 2 index:
id_message
reporting_id
J'ai msisdn
dans le tableau Message
mais il n'est pas indexé.
J'ai donc une interface utilisateur de tableau de bord qui me permet de rechercher Message
.
Je souhaite rechercher Message
en utilisant msisdn
mais comme msisdn
n'est pas indexé, la requête prend une éternité!
mais je veux mettre l'idée de "Indexer msisdn
dans la table Message
" comme plan B.
Mon plan A est donc (pour lequel j'ai besoin d'aide):
Étant donné que les deux tables ont indexé reporting_id
, je souhaite rechercher Message
en utilisant subscription.msisdn
dans le tableau de bord, puis à partir de là, Je souhaite utiliser le subscription.reporting_id
et lister tous les Message
avec cet subscription.reporting_id
.
Quelque chose comme subscription.reporting_id = message.reporting_id
.
J'ai la vue
, le contrôleur
et le modèle
pour ces 2 tables,
J'ai essayé de faire cela dans les deux modèles
has_many: message, Foreign_key:: reporting_id
dans Subscription.rb
et
appartient_à: abonnement
dans Message.rb
mais cela n'a pas fonctionné.
Dans ma vue
, le champ de recherche pour MSISDN
recherche actuellement l'enregistrement à partir de subscription.msisdn
Quelqu'un sait-il comment puis-je y parvenir?
PS: je souhaite empêcher de modifier la structure du tableau.
3 Réponses :
Si vous souhaitez établir une association has_many: messages
dans la classe Subscription, vous devrez spécifier la primary_key.
Message. joins("INNER JOIN subscriptions ON subscriptions.reporting_id = messages.reporting_id"). merge(Subscription.where(msisdn: "#{value}"))
Avec ceci, le SQL généré ressemblera à ceci:
SELECT "messages".* FROM "messages" WHERE "messages"."reporting_id" = $1 [["reporting_id", "#{reporting_id}"]]
La primary_key garantit la valeur de reporting_id
du modèle Subscription
est utilisé, sinon il sera par défaut dans la colonne id.
Cependant, plutôt que d'établir cette association qui ne semble pas exactement normalisée (au moins 3NF ), vous pouvez simplement avoir une requête pour trouver tous les messages en utilisant msisdn et reporting_id. Quelque chose comme celui-ci devrait toujours être efficace:
class Subscription < ApplicationRecord has_many :messages, foreign_key: "reporting_id", primary_key: "reporting_id" end
Merci pour votre réponse: D, j'ai essayé à la fois Kvr Ramya et votre suggestion, mais cela n'a pas fonctionné pour moi. Mais j'ai trouvé la solution basée sur le code de votre gars. J'ai écrit appartient_to: abonnement, clé étrangère: "reporting_id", primary_key: "reporting_id"
dans Message.rb
à la place.
doit également ajouter une clé primaire
has_many: message, Foreign_key:: reporting_id, primary_key:: reporting_id
dans Subscription.rb
Merci pour votre réponse: D, j'ai trouvé le correctif!
J'ai trouvé la solution!
Dans mon Message.rb
, j'ai fait:
SELECT `subscription`.* FROM `subscription` WHERE `subscription`.`reporting_id` = '1eaa7a61fe635005c81df347b1a7c401' LIMIT 1
et il a généré cette requête
belongs_to :subscription, foreign_key: :reporting_id, primary_key: :reporting_id
Les relations
has_many
doivent être plurielles, c'est-à-direhas_many: messages
.@MikeHeft, merci pour votre réponse, mais cela ne résout pas mon problème :(