PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment créer un index sur LOWER (users.username) dans Rails (en utilisant postgres)

Oui, cette validation ferait ce genre de requête et ce type de requête va faire une analyse de table.

Vous avez en fait quelques problèmes ici :

  • La validation est soumise à des conditions de concurrence car la logique n'est pas dans la base de données à laquelle elle appartient. La base de données devrait être responsable de tous les problèmes d'intégrité des données, quelle que soit l'idéologie Rails habituelle.
  • Votre validation déclenche des analyses de table et personne n'aime les analyses de table.

Vous pouvez résoudre ces deux problèmes avec un seul index. Le premier problème est résolu en utilisant un index unique à l'intérieur de la base de données. Le deuxième problème est résolu en indexant le résultat de lower(username) plutôt que username .

AFAIK Rails ne comprend toujours pas les index sur les expressions, vous devrez donc faire deux choses :

  1. Passer de schema.rb à structure.sql pour empêcher Rails d'oublier votre index. Dans votre config/application.rb vous souhaiterez définir :

    config.active_record.schema_format = :sql
    

    Vous devrez également commencer à utiliser le db:structure:* tâches de rake au lieu de db:schema:* Tâches. Une fois que vous êtes passé à structure.sql , vous pouvez supprimer db/schema.rb puisqu'il ne sera plus mis à jour ou utilisé ; vous voudrez également commencer à suivre db/structure.sql dans le contrôle de révision.

  2. Créez l'index à la main en écrivant un peu de SQL dans une migration. C'est facile :

    def up
      connection.execute(%q{
        create index idx_users_lower_username on users(lower(username))
      })
    end
    
    def down
      connection.execute(%q{
        drop index idx_users_lower_username
      })
    end
    

Bien sûr, cela vous laissera avec des éléments spécifiques à PostgreSQL, mais il n'y a pas lieu de s'inquiéter car ActiveRecord ne vous offre de toute façon aucune portabilité utile.