Domanda

Sto usando Fluent-NHibernate (con automapping) per generare i miei tavoli, ma vorrei scegliere un indice cluster diverso rispetto al campo ID che viene utilizzato per impostazione predefinita. Come si può creare indici cluster con Fluent NHibernate su un campo diverso da quello del campo chiave primaria di default?

Il ragionamento principale dietro questo è semplice. Sto usando GUID per i miei campi chiave primaria. Per impostazione predefinita, NHibernate crea indici cluster sui campi chiave primaria. Dal momento che GUID di solito non sono sequenziali, il clustering sul campo di chiave primaria provoca un problema di prestazioni.

Come tutti sappiamo, aggiungendo record alla fine di una tabella è un'operazione molto più conveniente che l'inserimento di record all'interno della tabella. Inoltre, i record nella tabella sono fisicamente memorizzati nel ordine degli elementi nell'indice cluster. Poiché GUID sono piuttosto "random" e non sono sequenziali, nuovi GUID possono essere generati che sono inferiori al valore di altre Id GUID già nella tabella -. Conseguente inserti tabella piuttosto che accodamento

Per ridurre al minimo questo, ho una colonna chiamata createdOn che è di tipo DateTime. Ho bisogno per la tavola da cluster su questa colonna createdOn in modo che tutti i nuovi record vengono aggiunti, piuttosto che inseriti.

Tutte le idee su come raggiungere questo obiettivo sono i benvenuti !!!

Nota:. Mi rendo conto che avrei potuto usare sequenziali GUID ma preferiscono non andare su questa strada per motivi di sicurezza


Nota: Io ancora non ho una risposta per questo post, ma ho un paio di idee che sto riflettendo in questo momento

.
  1. Utilizzo di NHibernate senza perfetto, penso che potrebbe essere possibile indici cluster creati direttamente in NHibernate. Io non so ancora abbastanza di NHibernate per sapere come fare questo. Io sono solo abbastanza (come in quasi assoluta) sicuro che può essere fatto.

  2. Ottima-NHibernate utilizzato per includere un modo per impostare attributi (ad esempio come un indice cluster) su un oggetto SQL prima della recente riscrittura. Ora che l'opzione sembra essere andato via. Io probabilmente inviare una domanda da qualche parte per vedere se tale opzione è ancora disponibile. Se è così, probabilmente potrei usare che per impostare l'indice cluster.

  3. Fluent-NHibernate offre la possibilità di esporre una configurazione per la modifica manuale una volta che è stata correntemente costruita. Non ho provato questa funzionalità ma si aspettano che può offrire il livello di granularità che è necessario per impostare gli indici cluster.

  4. Nella peggiore delle ipotesi, posso scrivere uno script SQL per modificare gli indici cluster su tutte le mie tabelle, una volta che vengono generate. Tuttavia, ho un paio di domande per quanto riguarda questo approccio. A. Dal momento che sto usando la generazione automatica dello schema, vi NHibernate "annullare" il mio indice cluster cambia la prossima volta che valuta la configurazione? 2. Errore di Will NHibernate se rileva l'indice cluster è stato cambiato? Ho bisogno di testare questo, ma non l'ho fatto appena ancora. Io odio questa soluzione però. Sto testando il mio DB contro SQLServer2008 e MySQL. Parte della bellezza di NHibernate è che si tratta di database agnostico. Una volta che si introduce script, tutte le scommesse sono spenti.

  5. V'è un'interfaccia che viene utilizzato nelle convenzioni fluente chiamati classi IPropertyInstance che ereditano da questa interfaccia avere una proprietà Index, che permette un indice da creare sul campo. Il problema è che non v'è alcuna bandiera o altra opzione per consentire l'indice per essere creato come cluster. La soluzione più semplice sarebbe quella di aggiungere una proprietà a questo metodo per consentire gli indici cluster da creare. Credo di poter suggerire questo agli sviluppatori Fluent-NHibernate.

È stato utile?

Soluzione

Questo è un vecchio post, ma spero potrebbe aiutare qualcun altro. Questo viene da mia esperienza su MS SQL Server. Credo piattaforme diverse richiedono soluzioni diverse, ma questo dovrebbe essere un buon punto di partenza.

NHibernate non imposta l'indice cluster sulla chiave primaria. E 'il comportamento predefinito di SQL Server. Come ci può essere un solo cluster per ogni tabella, dobbiamo prima di evitare la creazione cluster nella chiave primaria.

L'unico modo che ho trovato per raggiungere questo obiettivo è quello di creare un dialetto personalizzato, ignorando l'PrimaryKeyString propery. predefinito di NHibernate viene da Dialect.cs :

    public virtual string PrimaryKeyString
    {
        get { return "primary key"; }
    }

Per SQL Server

    public override string PrimaryKeyString
    {
        get { return "primary key nonclustered"; }
    }

Questo costringerà SQL Server per creare una chiave primaria NONCLUSTERED. Ora è possibile aggiungere il proprio indice cluster sulla colonna preferita attraverso il tag nel file di mapping XML.

<database-object>
  <create>
    create clustered index IX_CustomClusteredIndexName on TableName (ColumnName ASC)
  </create>
  <drop>
    drop index IX_CustomClusteredIndexName ON TableName
  </drop>
</database-object>

Altri suggerimenti

Non posso rispondere in modo specifico, ma vi darà alcune informazioni di database da quando sono qui.

È necessario dire NHibernate per creare la chiave primaria in un indice non cluster. Ci possono essere raggruppati solo unico indice per ogni tabella, quindi è necessario creare la tabella come un mucchio, e poi mettere un indice cluster su di esso.

Come hai detto tu stesso, un'altra opzione è quella di passare alla strategia di generazione ID guid.comb dove uid PK si basano su una parte che è un GUID e una parte che assicura che gli ID generati sono sequenziali.

Scopri ulteriori informazioni in un post da Jeffrey Palermo qui .

Ma si parla che non vogliono farlo per motivi di sicurezza - perché è che

Proprio come @ abx78 detto, questo è un vecchio post, ma vorrei condividere la mia knowledgde su una soluzione per questo problema pure. Ho costruito la soluzione per idea 3 "Fluent NHibernate espone mappature":

Dopo la configurazione è stato costruito (quindi le mappature vengono analizzati), Fluent NHibernate ci dà la possibilità di vedere sottacqua di esaminare le mappature reali con configuration.ClassMappings e configuration.CollectionMappings. Quest'ultimo è utilizzato nell'esempio di seguito per impostare una chiave primaria composito risultante in un indice cluster in SQL Server (come @ abx78 sottolinea):

foreach (var collectionMapping in configuration.CollectionMappings) {
    // Fetch the columns (in this example: build the columns in a hacky way)
    const string columnFormat = "{0}_id";
    var leftColumn = new Column(string.Format(
        columnFormat,
        collectionMapping.Owner.MappedClass.Name));
    var rightColumn = new Column(string.Format(
        columnFormat,
        collectionMapping.GenericArguments[0].Name));
    // Fetch the actual table of the many-to-many collection
    var manyToManyTable = collectionMapping.CollectionTable;
    // Shorten the name just like NHibernate does
    var shortTableName = (manyToManyTable.Name.Length <= 8)
                                ? manyToManyTable.Name
                                : manyToManyTable.Name.Substring(0, 8);
    // Create the primary key and add the columns
    // >> This part could be changed to a UniqueKey or to an Index
    var primaryKey = new PrimaryKey {
        Name = string.Format("PK_{0}", shortTableName),
    };
    primaryKey.AddColumn(leftColumn);
    primaryKey.AddColumn(rightColumn);
    // Set the primary key to the junction table
    manyToManyTable.PrimaryKey = primaryKey;
    // <<
}

Fonte: Fluent NHibernate:? Come creare un indice cluster su una relazione molti-a-molti join di tabella

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top