4
votes

Sauvegarder des enregistrements dans MySQL qui n'existent pas

Disons que j'ai une table prédéfinie appelée villes , avec presque toutes les villes de mon pays.

Lorsqu'un utilisateur s'inscrit lui-même (table des utilisateurs), la colonne cities_id dans la table user stocke l'identifiant de la ville à partir de la table villes ( Clé étrangère, ville de la table de référence), quelque chose comme

CREATE TABLE `user` (
    `id` int,
    `name` varchar(60)
    `****`
    `cities_id` FK
    `citiy name` varchar(100)
)

La table user stocke l'ID de la ville.

Mais que se passe-t-il si j'ai raté quelques villes ... . Comment l'utilisateur enregistre-t-il ensuite le nom de sa ville dans la table utilisateur qui n'accepte aucun nom de ville mais uniquement des identifiants?

Puis-je avoir une colonne supplémentaire city_name juste après le cities_id dans le tableau user quelque chose comme

CREATE TABLE `cities` (
    `id` int,
    `city_name` varchar(100)
)

CREATE TABLE `user` (
    `id` int,
    `name` varchar(60)
    `****`
    `cities_id` FK
)

pour enregistrer les données saisies par l'utilisateur au moment de l'inscription? Cela peut-il être fait?


4 commentaires

L'utilisateur ne peut pas, sauf s'il peut également créer une nouvelle ville dans le tableau cities


@Jaokim Danielson, comment Facebook fait-il cela? Lorsque vous remplissez la colonne de la ville, cela suggère le nom de votre ville et s'il n'existe pas, vous pouvez écrire le vôtre. Je pense que FB stocke l'identifiant de la ville cz lorsque vous cliquez sur le lien hypertexte de la ville dans un profil, il montre des lieux intéressants liés à ces villes


Eh bien, votre question est très large et vous ne savez pas comment vous voulez résoudre cela, dans le code client, dans le code côté serveur ou complètement en SQL? Mais la logique de base est très simple, si la ville n'existe pas, stockez-la et utilisez le nouvel identifiant de cette ville lors du stockage de l'utilisateur.


Voulez-vous permettre aux utilisateurs de saisir des données arbitraires dans le tableau des villes (et de faire toutes sortes de fautes de frappe, de doublons ou de noms inventés / non officiels)? Je vous suggère plutôt de télécharger les données à partir d'une source officielle / bien entretenue afin que la probabilité que quelqu'un ne trouve pas le nom de sa ville soit minime.


6 Réponses :


3
votes

Comme @Joakim l'a mentionné dans le commentaire, du point de vue de la base de données, comme cities_id est une clé étrangère faisant référence à la table cities, l'insertion d'un enregistrement dans la table user échouera si la ville en question n'est pas déjà présente dans la table.

Du point de vue de la programmation, si vous voulez qu'une ville qui n'est pas là dans le tableau soit d'abord insérée automatiquement chaque fois qu'un utilisateur s'inscrit, c'est possible. En supposant que vous utilisez Java et Hibernate et que l'entité User contient l'entité City, l'appel de la méthode saveOrUpdate () sur l'entité utilisateur entraînera l'insertion de l'enregistrement de la ville s'il n'est pas déjà là, et un enregistrement d'utilisateur sera alors inséré dans la table User.



3
votes

Voilà comment je pourrais rapidement résoudre ce problème

Créer une table supplémentaire pour stocker les villes manquantes, qui sera introduite par les utilisateurs

CREATE VIEW all_cities AS
SELECT id, city_name FROM `cities`
UNION ALL
SELECT id, city_name FROM `cities_users`;

Créez une VUE qui UNION les 2 tables de villes:

CREATE TABLE `cities_users` (
`id` int,
`city_name` varchar(100),
`added_by` varchar(100),
`added_TS` DATETIME DEFAULT CURRENT_TIMESTAMP
);

À chaque fois qu'un utilisateur s'inscrit, vous interrogez la VUE pour vérifier si la ville de l'utilisateur existe. De cette façon, vous saurez si une ville existe dans votre table d'origine OU les villes introduites par les utilisateurs.

Sinon, vous INSÉRER la nouvelle ville dans la table cities_users (avec l'utilisateur qui l'a créé à des fins de journalisation).

Vous devez générer correctement un identifiant unique, c'est-à-dire un identifiant qui ne peut jamais exister dans le tableau cities . Vous pouvez le faire de différentes manières, voici un exemple rapide: prenez le dernier identifiant de la table cities_users et ajoutez-y 1 million. Vos identifiants cities_users seront comme: 1000001, 1000002, 1000003

Et enfin, vous insérez l'identifiant cities_users généré dans la table users.

Avoir un tableau séparé pour les entrées utilisateur devrait vous aider pour garder la base de données propre:

  1. Votre tableau des villes d'origine reste totalement inchangé
  2. Vous saurez facilement à tout moment les nouvelles villes ajoutées par qui et quand, et vous pouvez créer une petite interface pour examiner et gérer cela.
  3. Vos utilisateurs travaillent pour vous pour compléter votre base de données.


2 commentaires

merci mon pote, votre suggestion a beaucoup de sens. J'aimerais essayer votre solution avant d'accepter votre réponse. Veuillez me donner un jour ou deux. Je reviendrai rapidement. Merci encore.


Pour une utilisation encore plus simple, l'insertion de villes manquantes dans cities_user pourrait être automatisée à l'aide d'un TRIGGER lorsqu'un nouvel utilisateur s'inscrit dans une ville inconnue. Cela vous éviterait d'interroger la vue en premier lieu.



2
votes

Si un utilisateur suggère une nouvelle ville, vous devez créer un nouvel enregistrement dans la table des villes et stocker city_id dans la table des utilisateurs. C'est la meilleure façon de stocker les enregistrements de table.


2 commentaires

Je ne veux pas perdre un utilisateur simplement parce que sa ville n'était pas déjà dans mes archives et c'est ce que j'essaie de résoudre. Si la ville de l'utilisateur n'est pas dans mon dossier, je veux toujours qu'il ajoute sa ville. Beaucoup de gens auront tendance à oublier qu'ils ont fait une demande et ne reviendront pas. Je trouve que Thomas G. répond beaucoup à ce que je recherche. Merci pour votre suggestion.


Je ne demandais pas de perdre un utilisateur car l'utilisateur est l'atout très précieux. Je demandais d'ajouter d'abord la ville, puis d'utiliser son identifiant dans la table des utilisateurs avec les détails de l'utilisateur. si vous ajoutez deux tableaux, vous rencontrerez un problème lors de la recherche à partir du tableau des villes.



6
votes

Vous pouvez ajouter un type à la balise de table de ville, l'utilisateur ne peut pas trouver leur correspondant à la ville lui permet de taper le nom de sa ville, puis vous dans la ville, et créera un enregistrement correspondant dans le tableau type marqué comme un statut spécial (contrôle et correction pratiques par le personnel d'exploitation), en même temps pour enregistrer l'identifiant d'enregistrement dans l'enregistrement utilisateur

CREATE TABLE `cities` (
    `id` int,
    `city_name` varchar(100),
    `type` int,
)

CREATE TABLE `user` (
    `id` int,
    `name` varchar(60)
    `****`
    `cities_id` FK
)


1 commentaires

J'aime cette idée, je me lance dans un CMS imaginaire qui vous permet d'approuver, de modifier, de combiner et de rejeter les villes suggérées par les utilisateurs :)



0
votes

Je pense qu'il faut souligner, malgré les réponses contraires, que votre suggestion initiale d'ajouter une colonne city_name au tableau fonctionnera assez bien

Si vous autorisez à la fois cities_id et city_name à être Nullable, vous pouvez valider qu'un seul d'entre eux est défini dans la logique de l'application

L'avantage de cette approche est qu'elle garderait votre table de ville «pure» et vous permettrait de compter les doublons et d'analyser facilement les villes fournies par l'utilisateur

Cela ajouterait cependant une colonne city_name nullable très clairsemée dans votre table

Je suppose que cela dépend de la façon dont vous voulez obtenir la ville de l'utilisateur, (liste déroulante + zone de texte pour les autres, zone de texte avec des suggestions, juste une zone de texte) et de ce que vous prévoyez de faire avec les villes que vous se sont rassemblés

Vous pouvez même changer le libellé en "ville (ou ville la plus proche)" avec une liste déroulante codée en dur ou une liste déroulante interrogeable, et ne pas autoriser les villes fournies par l'utilisateur


0 commentaires

0
votes

Si vous avez une table de tampons dans laquelle les données brutes sont placées, c'est-à-dire la relation entre nom_ville, nom_utilisateur

CREATE TABLE `buffer_city_user` (
`buffer_id` int,
`city_name` varchar(100),
`user_name` varchar(100),
);

vous pouvez d'abord traiter la table tampon pour les nouveaux noms de ville - si trouvé, insérez dans les villes de table.

Ensuite, insérez les informations utilisateur - tout nouveau nom de ville devrait déjà figurer dans le tableau des villes et aucun problème de clé étrangère ne se produira.


0 commentaires