Ce este maparea portului? Tehnologie pentru migrarea datelor în proiecte mari


În partea anterioară, am analizat tipurile de relații (unu-la-unu, unu-la-mulți, mulți-la-mulți), precum și o clasă Book și clasa sa de mapare BookMap. În a doua parte, vom actualiza clasa Book, vom crea clasele rămase și conexiunile între ele, așa cum a fost descris în capitolul anterior din Diagrama bazei de date situată deasupra subtitlului 1.3.1 Relații.

Codul claselor și mapărilor (Cu comentarii)

Cartea de clasă

Public class Book ( //Identificator unic public virtual int Id ( get; set; ) // Titlu public virtual string Nume ( get; set; ) // Descriere public virtual string Descriere ( get; set; ) // Rating of the World of Fiction public virtual int MfRaiting ( get; set; ) //Numere de pagină public virtual int PageNumber ( get; set; ) //Link către imagine public virtual string Image (get; set; ) //Data sosirii cărții (filtru) prin elemente noi!) public virtual DateTime IncomeDate ( get; set; ) //Gen (Mulți-la-Mulți) //De ce ISet și nu IList Numai o singură colecție (IList) poate fi selectată folosind JOIN fetch, dacă mai multe colecția este necesară pentru preluarea JOIN, atunci este mai bine să le convertiți într-o colecție ISet virtuală publică ISet Genuri ( get; set; ) //Serial (Multe-la-unu) Seria virtuală publică Seria (get; set; ) //Opinie și alte (Un-la-unu) private Mind _mind; public virtual Mind Mind ( get ( return _mind ?? (_mind = new Mind()); ) set ( _mind = valoare; ) ) ) //Autor (Mulți-la-mulți) ISet virtual public Authors ( get; set; ) //Inițializați în avans, astfel încât să nu apară o excepție nulă. public Book() ( //Set neordonat (un tabel nu poate avea două rânduri exact identice, altfel îl selectează pe unul și îl ignoră pe celălalt) Genres = nou HashSet (); Authors = nou HashSet (); ) ) //Clasa de cartografiere Book public class BookMap: ClassMap ( public BookMap() ( Id(x => x.Id); Harta(x => x.Nume); Harta(x => x.Descriere); Harta(x => x.MfRaiting); Harta(x = > x.PageNumber); Map(x => x.Image Map(x => x.IncomeDate); obiectul este salvat, actualizat sau șters, toate obiectele dependente sunt verificate și //created/updated/added.Cascade.SaveUpdate() //Numele tabelului intermediar TREBUIE să fie același cu clasa Genre .Table("Book_Genre" ); > x.Autori) .Cascade.SaveUpdate() .Table("Carte_Autor"); . => x.Mind).Cascade.All().Constrained();

Public class Author ( public virtual int Id ( get; set; ) //Nume-Prenume public virtual string Nume (get; set; ) //Biography public virtual string Biography ( get; set; ) //Books public virtual ISet Cărți ( obțineți; setați; ) //Inițializarea autorilor public Author() ( Cărți=new HashSet (); ) ) // Author Mapping clasa publică AuthorMap: ClassMap ( public AuthorMap() ( Id(x => x.Id); Harta(x => x.Nume); Harta(x => x.Biografie); //Relație multi-la-mulți HasManyToMany(x => x .Cărți) //Reguli în cascadă Toate - Când un obiect este salvat, actualizat sau șters, toate obiectele dependente sunt verificate și create/actualizate/adăugate.Cascade.All() //Deținătorul colecției este celălalt capăt al relației (Book) și va fi salvat mai întâi .Inverse() //Numele tabelului intermediar TREBUIE să fie același cu clasa Book!

Genul clasei

Clasa publică Gen ( public virtual int Id ( get; set; ) //Numele genului public virtual string Nume (get; set; ) //Numele în engleză al genului public virtual string EngName (get; set; ) //Cărți ISet virtual public Cărți ( obțineți; setați; ) //Inițializarea cărților public Genre() ( Cărți=nou HashSet (); ) ) //Clasă publică de cartografiere de gen GenreMap: ClassMap ( public GenreMap() ( Id(x => x.Id); Map(x => x.Name); Map(x => x.EngName); //Relație multi-la-mulți HasManyToMany(x => x .Cărți) //Reguli în cascadă Toate - Când un obiect este salvat, actualizat sau șters, toate obiectele dependente sunt verificate și create/actualizate/adăugate.Cascade.All() //Deținătorul colecției este celălalt capăt al relației (Book) și va fi salvat mai întâi .Inverse() //Numele tabelului intermediar TREBUIE să fie același cu clasa Book!

Opinie de clasă:

Public class Mind ( public virtual int Id ( get; set; ) //My opinion public virtual string MyMind ( get; set; ) //opinia lui Fantlab public virtual string MindFantLab ( get; set; ) //Book public virtual Book Book ( get; set ) ) //Mapping public MindMap:ClassMap ( public MindMap() ( Id(x => x.Id); Map(x => x.MyMind); Map(x => x.MindFantLab); //Relație unu-la-unu HasOne(x => x .Carte ); ) )

Ciclu de clasă (serie):

Clasa publică Series ( public virtual int Id ( get; set; ) public virtual string Name ( get; set; ) //Am creat un IList, nu un ISet, deoarece, în afară de Book, Series nu este asociat cu nimic altceva, deși tu poate face și ISset public virtual IList Cărți ( obțineți; setați; ) //Inițializarea cărților. Public Series() ( Cărți = listă nouă (); ) ) public class SeriesMap: ClassMap ( public SeriesMap() ( Id(x => x.Id); Map(x => x.Name); //Relație unu-la-mai multe HasMany(x => x.Carti) ////Proprietar al colecția celălalt capăt al relației (Carte) și va fi salvat mai întâi.

O mica explicatie
ISet virtual public Genuri(get;set;)
ISet virtual public Autorii ( obține; setează; )

De ce ISet , și nu, de exemplu, IList cunoscut pentru mulți ? Dacă folosim IList în loc de ISet și încercăm să rulăm proiectul, nu vom observa o mare diferență (vor fi create tabelele și clasele). Dar când adăugăm tabelele Gen și Authors la clasa Book LeftJoin în același timp și încercăm, de asemenea, să afișăm înregistrări care nu se repetă din tabelul Book (Distinct Book.Id) într-o vizualizare (View), Nhibernate va arunca un excepție și o eroare.
Nu se pot prelua simultan mai multe pungi.
În astfel de cazuri, folosim ISet, mai ales că seturile sunt destinate pentru aceasta (ele ignoră înregistrările duplicate).

Relație de la mulți la mulți.

NHibernate are conceptul de tabel „principal”. Deși relația multi-la-mulți dintre tabelele Carte și Autor este echivalentă (Un autor poate avea multe cărți, o carte poate avea mulți autori), Nhibernate solicită programatorului să specifice tabelul care este stocat al doilea (are o metodă. invers ()), adică mai întâi se va crea/actualiza/șterge o înregistrare în tabelul Book, și abia apoi în tabelul Autor.
Cascade.All înseamnă efectuarea de operațiuni în cascadă la salvare, actualizare și ștergere. Adică, atunci când un obiect este salvat, actualizat sau șters, toate obiectele dependente sunt verificate și create/actualizate/adăugate (Ps. Poate fi scris în loc de Cascade.All -> .Cascade.SaveUpdate().Cascade.Delete())
Method.Table("Carte_Autor"); creează un tabel „intermediar” „Carte_Autor” în baza de date.

Relație multi-la-unu, unu-la-mulți.

Metoda.Constrained() îi spune lui NHibernate că o înregistrare din tabelul Book trebuie să se potrivească cu o înregistrare din tabelul Mind (id-ul tabelului Mind trebuie să fie egal cu id-ul tabelului Book)

Dacă acum rulați proiectul și vă uitați la baza de date Bibilioteca, vor apărea noi tabele cu conexiuni deja formate.

Apoi, completați tabelele create cu date...
Pentru a face acest lucru, vom crea o aplicație de testare care va salva datele în baza de date, o va actualiza și va șterge, schimbând HomeController-ul după cum urmează (comentăm secțiunile inutile ale codului):
public ActionResult Index() (folosind (sesiune ISession = NHibernateHelper.OpenSession()) (folosind (iTransaction tranzacție = session.BeginTransaction()) ( //Creați, adăugați var createBook = carte nouă(); createBook.Name = "Metro2033" ; createBook.Description = "Misticism post-apocaliptic"; ( Nume = "Metro" ); createBook.Mind = new Mind ( MyMind = "Misticism post-apocaliptic" ); (1); //var updateBook = session.Get (1); //updateBook.Name = "Metro2034"; //updateBook.Description = "Distopie"; //updateBook.Authors.ElementAt(0).Name = „Glukhovsky”; //updateBook.Genres.ElementAt(0).Name = „Dystopie”; //updateBook.Series = serie; //updateBook.Mind.MyMind = "11111"; //session.SaveOrUpdate(updateBook); //Delete (După ID) //var deleteBook = session.Get (1); //session.Delete(deleteBook); tranzacție.Commit(); ) Gen genreAl = null; Autor autorAl = nul; Seria serieAl = nulă; Mind mindAl = nul; var books = session.QueryOver () //Left Join with table Genres .JoinAlias(p => p.Genres, () => .JoinAlias(p => p.Authors, () => authorAl, JoinType.LeftOuterJoin) .JoinAlias(p => p .Series, () => seriesAl, JoinType.LeftOuterJoin). (); return View(carti);

O mica explicatie

  1. var books = session.QueryOver () Selectați * Din carte;
  2. .JoinAlias(p => p.Genuri, () => genreAl, JoinType.LeftOuterJoin)- similar cu executarea unui script SQL:
    SELECTAȚI *DIN Carte
    interior JOIN Book_Genre ON book.id = Book_Genre.Book_id
    LEFT JOIN Gen ACTIVAT Book_Genre.Genre_id = Genre.id
  3. .TransformUsing(Transformers.DistinctRootEntity)- Similar cu executarea unui script SQL: SELECTează carte. Id. distinctă..., (elimină înregistrările duplicate cu același id)

Tipuri de asociații
.JoinAlias(p => p.Genuri, () => genreAl, JoinType.LeftOuterJoin)

  1. LeftOuterJoin - selectează toate înregistrările din tabelul din stânga ( Carte), apoi le adaugă înregistrările de tabel potrivite ( Gen). Dacă o intrare corespunzătoare nu este găsită în tabelul din dreapta, o afișează ca Null
  2. RightOuterJoin este opusul LEFT JOIN - selectează toate înregistrările din tabelul din dreapta ( Gen), apoi le adaugă înregistrările din tabelul din stânga ( Carte)
  3. InnerJoin - selectează numai acele înregistrări din tabelele din stânga ( Carte) care are o intrare corespunzătoare din tabelul din dreapta ( Gen), apoi le unește cu înregistrările din tabelul din dreapta

Să schimbăm reprezentarea după cum urmează:

Vedere index

@modelul IEnumerable @( Aspect = nul; ) Index

@Html.ActionLink(„Creează nou”, „Creează”)

@foreach (var element din model) ( @(string strSeries = item.Series != null ? item.Series.Name: null;) }
@Html.DisplayNameFor(model => model.Name) @Html.DisplayNameFor(model => model.Mind) @Html.DisplayNameFor(model => model.Series) @Html.DisplayNameFor(model => model.Authors) @Html.DisplayNameFor(model => model.Genuri) Operațiuni
@Html.DisplayFor(modelItem => item.Name) @Html.DisplayFor(modelItem => item.Mind.MyMind)@Html.DisplayFor(modelItem => strSeries) @foreach (var autor în item.Authors) ( șir strAuthor = autor != null ? autor.Nume: null; @Html.DisplayFor(modelItem => strAuthor)
}
@foreach (var gen în item.Genres) ( string strGenre = gen!= null ? genre.Name: null; @Html.DisplayFor(modelItem => strGenre)
}
@Html.ActionLink(„Editare”, „Editare”, nou ( id = item.Id )) | @Html.ActionLink(„Detalii”, „Detalii”, new ( id = item.Id )) | @Html.ActionLink(„Șterge”, „Șterge”, nou ( id = item.Id ))




După ce am verificat toate operațiunile una câte una, vom observa că:
  • În timpul operațiunilor de creare și actualizare, toate datele asociate cu tabelul Book sunt actualizate (eliminați Cascade="save-update" sau cascade="all" și datele asociate nu vor fi salvate)
  • La ștergere, datele sunt șterse din tabelele Book, Mind, Book_Author, dar datele rămase nu sunt șterse deoarece au Cascade="save-update"

Mapare pentru clasele care au moștenire.
Cum să mapați clasele care au moștenire? Să presupunem că avem acest exemplu:
//Class of Two-Dimensional Shapes public class TwoDShape ( //Width public virtual int Width ( get; set; ) // Height public virtual int Height ( get; set; ) ) // Class Triangle public class Triangle: TwoDShape ( // /Număr de identificare public virtual int Id (get; set; ) //Tipul triunghiului public virtual șir Stil (get; set; ) )

În principiu, nu este nimic complicat în această mapare, vom crea pur și simplu o mapare pentru clasa derivată, adică tabelul Triunghi.
//Cartografierea triunghiului clasă publică TriangleMap: ClassMap ( public TriangleMap() ( Id(x => x.Id); Harta(x => x.Stil); Harta(x => x.Înălțime); Hartă(x => x.Lățime); ) )
După lansarea aplicației, următorul tabel (vid) va apărea în baza de date Biblioteca

Etichete:

  • asp.net mvc 4
  • nhiberna
  • SQL Server
Adaugă etichete
Partea 3: Afișarea datelor dintr-un tabel (operația LIST)

În partea anterioară, am analizat tipurile de relații (unu-la-unu, unu-la-mulți, mulți-la-mulți), precum și o clasă Book și clasa sa de mapare BookMap. În a doua parte, vom actualiza clasa Book, vom crea clasele rămase și conexiunile între ele, așa cum a fost descris în capitolul anterior din Diagrama bazei de date situată deasupra subtitlului 1.3.1 Relații.

Codul claselor și mapărilor (Cu comentarii)

Cartea de clasă

Public class Book ( //Identificator unic public virtual int Id ( get; set; ) // Titlu public virtual string Nume ( get; set; ) // Descriere public virtual string Descriere ( get; set; ) // Rating of the World of Fiction public virtual int MfRaiting ( get; set; ) //Numere de pagină public virtual int PageNumber ( get; set; ) //Link către imagine public virtual string Image (get; set; ) //Data sosirii cărții (filtru) prin elemente noi!) public virtual DateTime IncomeDate ( get; set; ) //Gen (Mulți-la-Mulți) //De ce ISet și nu IList Numai o singură colecție (IList) poate fi selectată folosind JOIN fetch, dacă mai multe colecția este necesară pentru preluarea JOIN, atunci este mai bine să le convertiți într-o colecție ISet virtuală publică ISet Genuri ( get; set; ) //Serial (Multe-la-unu) Seria virtuală publică Seria (get; set; ) //Opinie și alte (Un-la-unu) private Mind _mind; public virtual Mind Mind ( get ( return _mind ?? (_mind = new Mind()); ) set ( _mind = valoare; ) ) ) //Autor (Mulți-la-mulți) ISet virtual public Authors ( get; set; ) //Inițializați în avans, astfel încât să nu apară o excepție nulă. public Book() ( //Set neordonat (un tabel nu poate avea două rânduri exact identice, altfel îl selectează pe unul și îl ignoră pe celălalt) Genres = nou HashSet (); Authors = nou HashSet (); ) ) //Clasa de cartografiere Book public class BookMap: ClassMap ( public BookMap() ( Id(x => x.Id); Harta(x => x.Nume); Harta(x => x.Descriere); Harta(x => x.MfRaiting); Harta(x = > x.PageNumber); Map(x => x.Image Map(x => x.IncomeDate); obiectul este salvat, actualizat sau șters, toate obiectele dependente sunt verificate și //created/updated/added.Cascade.SaveUpdate() //Numele tabelului intermediar TREBUIE să fie același cu clasa Genre .Table("Book_Genre" ); > x.Autori) .Cascade.SaveUpdate() .Table("Carte_Autor"); . => x.Mind).Cascade.All().Constrained();

Public class Author ( public virtual int Id ( get; set; ) //Nume-Prenume public virtual string Nume (get; set; ) //Biography public virtual string Biography ( get; set; ) //Books public virtual ISet Cărți ( obțineți; setați; ) //Inițializarea autorilor public Author() ( Cărți=new HashSet (); ) ) // Author Mapping clasa publică AuthorMap: ClassMap ( public AuthorMap() ( Id(x => x.Id); Harta(x => x.Nume); Harta(x => x.Biografie); //Relație multi-la-mulți HasManyToMany(x => x .Cărți) //Reguli în cascadă Toate - Când un obiect este salvat, actualizat sau șters, toate obiectele dependente sunt verificate și create/actualizate/adăugate.Cascade.All() //Deținătorul colecției este celălalt capăt al relației (Book) și va fi salvat mai întâi .Inverse() //Numele tabelului intermediar TREBUIE să fie același cu clasa Book!

Genul clasei

Clasa publică Gen ( public virtual int Id ( get; set; ) //Numele genului public virtual string Nume (get; set; ) //Numele în engleză al genului public virtual string EngName (get; set; ) //Cărți ISet virtual public Cărți ( obțineți; setați; ) //Inițializarea cărților public Genre() ( Cărți=nou HashSet (); ) ) //Clasă publică de cartografiere de gen GenreMap: ClassMap ( public GenreMap() ( Id(x => x.Id); Map(x => x.Name); Map(x => x.EngName); //Relație multi-la-mulți HasManyToMany(x => x .Cărți) //Reguli în cascadă Toate - Când un obiect este salvat, actualizat sau șters, toate obiectele dependente sunt verificate și create/actualizate/adăugate.Cascade.All() //Deținătorul colecției este celălalt capăt al relației (Book) și va fi salvat mai întâi .Inverse() //Numele tabelului intermediar TREBUIE să fie același cu clasa Book!

Opinie de clasă:

Public class Mind ( public virtual int Id ( get; set; ) //My opinion public virtual string MyMind ( get; set; ) //opinia lui Fantlab public virtual string MindFantLab ( get; set; ) //Book public virtual Book Book ( get; set ) ) //Mapping public MindMap:ClassMap ( public MindMap() ( Id(x => x.Id); Map(x => x.MyMind); Map(x => x.MindFantLab); //Relație unu-la-unu HasOne(x => x .Carte ); ) )

Ciclu de clasă (serie):

Clasa publică Series ( public virtual int Id ( get; set; ) public virtual string Name ( get; set; ) //Am creat un IList, nu un ISet, deoarece, în afară de Book, Series nu este asociat cu nimic altceva, deși tu poate face și ISset public virtual IList Cărți ( obțineți; setați; ) //Inițializarea cărților. Public Series() ( Cărți = listă nouă (); ) ) public class SeriesMap: ClassMap ( public SeriesMap() ( Id(x => x.Id); Map(x => x.Name); //Relație unu-la-mai multe HasMany(x => x.Carti) ////Proprietar al colecția celălalt capăt al relației (Carte) și va fi salvat mai întâi.

O mica explicatie
ISet virtual public Genuri(get;set;)
ISet virtual public Autorii ( obține; setează; )

De ce ISet , și nu, de exemplu, IList cunoscut pentru mulți ? Dacă folosim IList în loc de ISet și încercăm să rulăm proiectul, nu vom observa o mare diferență (vor fi create tabelele și clasele). Dar când adăugăm tabelele Gen și Authors la clasa Book LeftJoin în același timp și încercăm, de asemenea, să afișăm înregistrări care nu se repetă din tabelul Book (Distinct Book.Id) într-o vizualizare (View), Nhibernate va arunca un excepție și o eroare.
Nu se pot prelua simultan mai multe pungi.
În astfel de cazuri, folosim ISet, mai ales că seturile sunt destinate pentru aceasta (ele ignoră înregistrările duplicate).

Relație de la mulți la mulți.

NHibernate are conceptul de tabel „principal”. Deși relația multi-la-mulți dintre tabelele Carte și Autor este echivalentă (Un autor poate avea multe cărți, o carte poate avea mulți autori), Nhibernate solicită programatorului să specifice tabelul care este stocat al doilea (are o metodă. invers ()), adică mai întâi se va crea/actualiza/șterge o înregistrare în tabelul Book, și abia apoi în tabelul Autor.
Cascade.All înseamnă efectuarea de operațiuni în cascadă la salvare, actualizare și ștergere. Adică, atunci când un obiect este salvat, actualizat sau șters, toate obiectele dependente sunt verificate și create/actualizate/adăugate (Ps. Poate fi scris în loc de Cascade.All -> .Cascade.SaveUpdate().Cascade.Delete())
Method.Table("Carte_Autor"); creează un tabel „intermediar” „Carte_Autor” în baza de date.

Relație multi-la-unu, unu-la-mulți.

Metoda.Constrained() îi spune lui NHibernate că o înregistrare din tabelul Book trebuie să se potrivească cu o înregistrare din tabelul Mind (id-ul tabelului Mind trebuie să fie egal cu id-ul tabelului Book)

Dacă acum rulați proiectul și vă uitați la baza de date Bibilioteca, vor apărea noi tabele cu conexiuni deja formate.

Apoi, completați tabelele create cu date...
Pentru a face acest lucru, vom crea o aplicație de testare care va salva datele în baza de date, o va actualiza și va șterge, schimbând HomeController-ul după cum urmează (comentăm secțiunile inutile ale codului):
public ActionResult Index() (folosind (sesiune ISession = NHibernateHelper.OpenSession()) (folosind (iTransaction tranzacție = session.BeginTransaction()) ( //Creați, adăugați var createBook = carte nouă(); createBook.Name = "Metro2033" ; createBook.Description = "Misticism post-apocaliptic"; ( Nume = "Metro" ); createBook.Mind = new Mind ( MyMind = "Misticism post-apocaliptic" ); (1); //var updateBook = session.Get (1); //updateBook.Name = "Metro2034"; //updateBook.Description = "Distopie"; //updateBook.Authors.ElementAt(0).Name = „Glukhovsky”; //updateBook.Genres.ElementAt(0).Name = „Dystopie”; //updateBook.Series = serie; //updateBook.Mind.MyMind = "11111"; //session.SaveOrUpdate(updateBook); //Delete (După ID) //var deleteBook = session.Get (1); //session.Delete(deleteBook); tranzacție.Commit(); ) Gen genreAl = null; Autor autorAl = nul; Seria serieAl = nulă; Mind mindAl = nul; var books = session.QueryOver () //Left Join with table Genres .JoinAlias(p => p.Genres, () => .JoinAlias(p => p.Authors, () => authorAl, JoinType.LeftOuterJoin) .JoinAlias(p => p .Series, () => seriesAl, JoinType.LeftOuterJoin). (); return View(carti);

O mica explicatie

  1. var books = session.QueryOver () Selectați * Din carte;
  2. .JoinAlias(p => p.Genuri, () => genreAl, JoinType.LeftOuterJoin)- similar cu executarea unui script SQL:
    SELECTAȚI *DIN Carte
    interior JOIN Book_Genre ON book.id = Book_Genre.Book_id
    LEFT JOIN Gen ACTIVAT Book_Genre.Genre_id = Genre.id
  3. .TransformUsing(Transformers.DistinctRootEntity)- Similar cu executarea unui script SQL: SELECTează carte. Id. distinctă..., (elimină înregistrările duplicate cu același id)

Tipuri de asociații
.JoinAlias(p => p.Genuri, () => genreAl, JoinType.LeftOuterJoin)

  1. LeftOuterJoin - selectează toate înregistrările din tabelul din stânga ( Carte), apoi le adaugă înregistrările de tabel potrivite ( Gen). Dacă o intrare corespunzătoare nu este găsită în tabelul din dreapta, o afișează ca Null
  2. RightOuterJoin este opusul LEFT JOIN - selectează toate înregistrările din tabelul din dreapta ( Gen), apoi le adaugă înregistrările din tabelul din stânga ( Carte)
  3. InnerJoin - selectează numai acele înregistrări din tabelele din stânga ( Carte) care are o intrare corespunzătoare din tabelul din dreapta ( Gen), apoi le unește cu înregistrările din tabelul din dreapta

Să schimbăm reprezentarea după cum urmează:

Vedere index

@modelul IEnumerable @( Aspect = nul; ) Index

@Html.ActionLink(„Creează nou”, „Creează”)

@foreach (var element din model) ( @(string strSeries = item.Series != null ? item.Series.Name: null;) }
@Html.DisplayNameFor(model => model.Name) @Html.DisplayNameFor(model => model.Mind) @Html.DisplayNameFor(model => model.Series) @Html.DisplayNameFor(model => model.Authors) @Html.DisplayNameFor(model => model.Genuri) Operațiuni
@Html.DisplayFor(modelItem => item.Name) @Html.DisplayFor(modelItem => item.Mind.MyMind)@Html.DisplayFor(modelItem => strSeries) @foreach (var autor în item.Authors) ( șir strAuthor = autor != null ? autor.Nume: null; @Html.DisplayFor(modelItem => strAuthor)
}
@foreach (var gen în item.Genres) ( string strGenre = gen!= null ? genre.Name: null; @Html.DisplayFor(modelItem => strGenre)
}
@Html.ActionLink(„Editare”, „Editare”, nou ( id = item.Id )) | @Html.ActionLink(„Detalii”, „Detalii”, new ( id = item.Id )) | @Html.ActionLink(„Șterge”, „Șterge”, nou ( id = item.Id ))




După ce am verificat toate operațiunile una câte una, vom observa că:
  • În timpul operațiunilor de creare și actualizare, toate datele asociate cu tabelul Book sunt actualizate (eliminați Cascade="save-update" sau cascade="all" și datele asociate nu vor fi salvate)
  • La ștergere, datele sunt șterse din tabelele Book, Mind, Book_Author, dar datele rămase nu sunt șterse deoarece au Cascade="save-update"

Mapare pentru clasele care au moștenire.
Cum să mapați clasele care au moștenire? Să presupunem că avem acest exemplu:
//Class of Two-Dimensional Shapes public class TwoDShape ( //Width public virtual int Width ( get; set; ) // Height public virtual int Height ( get; set; ) ) // Class Triangle public class Triangle: TwoDShape ( // /Număr de identificare public virtual int Id (get; set; ) //Tipul triunghiului public virtual șir Stil (get; set; ) )

În principiu, nu este nimic complicat în această mapare, vom crea pur și simplu o mapare pentru clasa derivată, adică tabelul Triunghi.
//Cartografierea triunghiului clasă publică TriangleMap: ClassMap ( public TriangleMap() ( Id(x => x.Id); Harta(x => x.Stil); Harta(x => x.Înălțime); Hartă(x => x.Lățime); ) )
După lansarea aplicației, următorul tabel (vid) va apărea în baza de date Biblioteca

Etichete: Adăugați etichete

Dragi prieteni!

Astăzi suntem încântați să vă informăm că dezvoltatorii noștri au implementat capacitatea de a transporta date prin URL (mapping) dincolo de pagina țintă.

Folosind această funcție, puteți transfera toate datele din câmpurile formularului pe pagina la care merge utilizatorul atunci când vă trimite un client potențial. Datorită acestui fapt, lead-ul nu numai că intră în , ci poate intra imediat în baza ta de date dacă este „întâlnit” de scriptul corespunzător de pe pagina de redirecționare.

Acum nu mai este nevoie să exportați date din sistemul de procesare a lead-urilor! Le poți trimite și procesa imediat în propria ta bază de date!

De asemenea, datorită acestei funcții, devine posibilă felicitarea sau mulțumirea utilizatorului care a furnizat personal informațiile sale de contact.

Cum funcționează cartografierea?

Esența mapării este că atunci când se trimit date din câmpurile de formular, conținutul acestora este adăugat la linkul către care are loc redirecționarea. Adresa URL devine: //my_site.com/?name=NAME&email=EMAIL_ADDRESS&phone=PHONE_NUMBER&lead_id=225298.

Important! Pe lângă toate datele câmpului, ID-ul clientului potențial este întotdeauna transmis în parametrul lead_id.

Pe pagina către care se face tranziția, aceste informații sunt „primite” de un script special, care, la rândul său, distribuie datele în „celulele” corespunzătoare.

Atrageți-vă atenția asupra! Maparea funcționează numai dacă „Rezultatul formularului” este „Mergeți la URL”!

Cum pot configura „transportul” unui client potențial după adresa URL (mapping) pe pagina mea de destinație?

1. Conectați-vă.
2. Selectați pagina cu formularul de lead din care veți „difuza” datele.

3. În editor, faceți dublu clic pe formular.

4. În fereastra care apare, completați coloana „Mapping” cu numele câmpurilor corespunzătoare în limba engleză. De exemplu, nume - nume, telefon - telefon etc.

5. Salvați modificările.

6. În proprietățile formularului, configurați o redirecționare către pagina dorită - aceasta ar putea fi o pagină a site-ului dvs. care are JavaScript încorporat, care va procesa datele din câmpurile primite de la adresa URL.

Bifați caseta de selectare „Pas form fields”.

7. Salvați modificările în meniul principal al editorului.

Asta e tot! :-)

Acum datele din câmpurile formularului dumneavoastră vor fi transferate către pagina către care redirecționați utilizatorul. Nu trebuie să exportați clienții potențiali din CRM LPgenerator - acestea pot fi „transportate” în CRM-ul dvs. direct prin URL. Posibilitățile de cartografiere pentru transportul datelor sunt cu adevărat nelimitate.

În acest articol, am dori să sistematizăm experiența noastră în realizarea migrării datelor în proiecte corporative mari legate de tranziția Clienților la lucru în configurațiile 1C:Enterprise 8.

Totodată, accentul principal în articol va fi pus, în primul rând, pe componenta tehnologică a procesului de migrare. Este afectată și componenta organizatorică, dar într-o măsură mai mică.

Termeni și definiții

Migrarea datelor este de obicei înțeleasă ca o secvență finală de lucru, un proiect care vizează o mișcare unică în masă a datelor de la sistemele sursă (sisteme istorice) la sistemul de destinație. În același timp, exploatarea acestor date în sistemele sursă încetează.

Migrarea datelor trebuie să fie diferențiată de integrarea datelor. Integrarea, spre deosebire de migrare, este o parte permanentă a arhitecturii IT și este responsabilă pentru fluxul de date între diferite sisteme și depozite de date - și este mai degrabă un proces decât o activitate de proiect.

Schema de migrare în general arată astfel:

Orez. 1

Sisteme istorice- bazele de date ale companiei Clientului, care sunt planificate a fi înlocuite total sau parțial la implementarea unui nou sistem.

Sistem receptor- sistem țintă, configurație arbitrară „1C:Enterprise 8”.

Datele inițiale- date descărcate din sistemele istorice într-un format de fișier xls personalizat. În acest caz, formatul xls pare a fi unul dintre cele mai convenabile, deoarece capacitatea de a încărca într-un fișier xls este prezentă în multe sisteme de contabilitate ale „generațiilor anterioare”.

Ca alternativă modernă, este posibil să se considere formatul de fișier xml ca un transport.

Există, de asemenea, opțiuni pentru utilizarea unei baze de date intermediare.

Transformare, conversie- procesul de conversie a datelor sursă în date pentru încărcare. Transformarea datelor are loc în conformitate cu șabloanele de încărcare. Rezultatul transformării sunt datele care trebuie încărcate.

Descărcați date- date destinate încărcării în sistemul receptor. Acest articol, precum și datele sursă, iau în considerare formatul xls.

Șabloane de date pentru încărcare- descrierea tabelelor de date care urmează să fie încărcate în sistemul țintă.

Etapele migrației

Să luăm în considerare procesul de pregătire și desfășurare a migrației pas cu pas.

Etapele organizatorice ale migrației includ următoarele puncte:

· Definirea unei strategii de migrare. În această etapă, Antreprenorul și Clientul convin asupra tehnologiei pentru efectuarea lucrărilor de migrare;

· Determinarea componenței grupului de lucru migrație. Grupul de lucru ar trebui să includă specialiști atât din partea Antreprenorului, cât și a Clientului, care sunt suficient de familiarizați cu funcționarea sistemelor istorice (din partea Clientului) și cu sistemul țintă (din partea Antreprenorului);

· Plan preliminar de migrare. Planul de migrare va fi ajustat de mai multe ori pe măsură ce proiectul avansează;

· Perioade de date pentru descărcarea datelor din sistemele istorice, volume de date. Perioadele de limitare a datelor pentru migrare, datele de testare și migrarea finală. Aceste informații pot fi atribuite planului de migrare;

· Compoziția datelor de migrat. Date de referință, clasificatoare, date despre tranzacții, solduri, cifra de afaceri etc.;

· Probleme de verificare a calității, corectitudinii și integrității datelor în timpul procesului de migrare și la final;

· Probleme de revenire la o stare anterioară în caz de eșecuri.

Să aruncăm o privire mai atentă asupra etapelor tehnologice ale migrației.

Orez. 2

1.Pregătirea șabloanelor de încărcare a datelor

Șablonul de încărcare a datelor conține descrieri tehnice ale tabelelor de date care trebuie încărcate, algoritmi și reguli de încărcare pentru șablonul curent.

Fiecare șablon vizează, în general, unul sau mai multe tabele înrudite pe sistemul țintă.

Șablonul afirmă:

· Descrierea tuturor câmpurilor fișierului de date xls pentru descărcare, inclusiv:

o Nume câmp

o Indicator că câmpul trebuie completat

o Exemplu de completare a câmpului

o Notă

· Descrierea regulilor de încărcare a tabelului de sistem țintă pe baza datelor de încărcat (coadă în cazul mai multor tabele înrudite, algoritmi de căutare pentru câmpurile cheie etc.)

· Descrierea completării directă a câmpurilor din tabelele sistemului țintă, dacă este furnizat altceva decât transferul de date „unu la unu” dintr-un fișier de date pentru încărcare. Relevant pentru câmpurile de referință, de exemplu.

În timpul lucrărilor în această etapă, Antreprenorul trebuie să pregătească și un încărcător de fișiere de date pentru încărcare. Când lucrați cu fișiere xls, această sarcină nu este deosebit de dificilă.

2.Identificarea surselor de date

Această etapă poate începe împreună cu etapa anterioară „1. Se pregătesc șabloane de încărcare a datelor.”

În această etapă, specialiștii Clientului stabilesc din ce sisteme și ce date pot fi descărcate. De asemenea, ar trebui să stabiliți ce date Pot fi poate fi nevoie.

De regulă, în proiectele mari de migrare, identificarea unei liste exhaustive complete de surse de date poate dura destul de mult și are loc pe măsură ce lucrările continuă în etapele ulterioare.

Există adesea situații în care, pentru a asigura în continuare integritatea informațiilor, unele date trebuie transferate din surse tipărite (digitizate) sau chiar introduse în tabele conform cuvintelor angajaților cheie ai Clientului.

Cu toate acestea, în această etapă ar trebui să încercați să identificați cât mai multe date necesare.

3.Încărcarea datelor sursă

Procesul de descărcare a datelor din sistemele istorice poate dura destul de mult, mai ales dacă există multe sisteme, acestea sunt diferite și diferite divizii ale Clientului sunt responsabile pentru acestea. Acest punct trebuie luat în considerare în timpul testării și migrațiilor finale.

Cea mai convenabilă opțiune pare să fie încărcarea în fișiere xls. Multe sisteme IT mai vechi acceptă această opțiune.

Pot exista și opțiuni de încărcare în format csv, dbf, xml și altele.

Este de remarcat faptul că dintr-un motiv sau altul (probleme de securitate, de exemplu), Clientul nu poate furniza întotdeauna descărcări de date în întregime în această etapă! Doar o structură de date și câteva poziții de testare. Astfel, poate apărea o situație în care în timpul testului și al încărcărilor finale, în tabelele sursă să fie detectate date de calitate scăzută, ceea ce va duce la erori neplanificate.

Pentru a minimiza această problemă, volumul descărcărilor de testare din sistemele istorice ar trebui convenit în avans.

4.Cartarea datelor

Mapping (data mapping) - în general, procesul de comparare a datelor din sistemele istorice și sistemul de recepție. Adică datele sursă și datele de încărcat.

Etapa de cartografiere este cea mai intensă etapă de muncă și poate ocupa mai mult de 50% din întreaga activitate a sarcinii de migrare.

În această etapă, întregul grup de lucru al proiectului de migrație este pe deplin implicat.

În procesul de mapare a datelor, este necesar să se distingă subetapele mapării tabelelor și mapării câmpurilor.

· Maparea tabelelor sau maparea șabloanelor - compararea tabelelor de date sursă și a șabloanelor de date pentru încărcare. Meciul poate fi 1:1 sau N:N. Ca rezultat al acestei lucrări, un registru de mapare a tabelelor este compilat și menținut. Această subetapă este necesară pentru următoarea subetapă a cartografierii câmpului și pentru monitorizarea stării generale a lucrurilor în cartografiere.

Grup de șabloane 1C

Numele șablonului 1C

Nume de fișier-

sursă

Reguli pentru generarea unui fișier sursă

Responsabil

stare

Notă

NSI

Probă_

Nomenclatură

Nomenk

latura.xls

Setați selecția în sistemul N
. Salvați în txt
. Deschide în xls, coloanele sunt text
. Prima linie este antetul
. Număr de coloane - 15
. Verificați numărul de linii în txt și xls
. Numele foii este întotdeauna „Sheet1”

Ivanov I.I.

la locul de muncă

· Maparea câmpurilor - maparea câmpurilor de tabel într-o mapare a tabelului deja definită. Rezultatul acestei lucrări este un registru de cartografiere a câmpurilor.

№pp

Cl. camp

Necesar

Numele câmpului șablonului 1C „Template_Nomenclature”

Descriere

Numele câmpului „Nomenclature.xls”

Algoritm de umplere

Cod

Cod element de director

Cod

Nume

Nume

da

Acest grup

Conține una dintre următoarele valori:
. 1 - pentru grupuri
. 0 - pentru elemente

Dacă lungimea codului=11 caractere și ultimele 4 caractere<>„0000”, atunci acest element este „0”, în caz contrar grupul este „1”.

Numele complet

Nume element de director

Nume

Dacă ThisGroup = 1, Atunci "", ElseIf ThisGroup = 0, atunci Nume.

Ca parte a acestei etape, ar trebui efectuate și posibile lucrări privind normalizarea datelor.

5.Pregătirea regulilor de transformare

Spre deosebire de etapele anterioare, această etapă este tehnică și implică munca dezvoltatorului Antreprenor.

Pe baza registrelor de cartografiere a terenului agreate, specialiștii Antreprenorului dezvoltă reguli pentru transformarea datelor.

Pentru munca operațională în timpul etapelor pregătitoare ale migrării și ulterior, în timpul testării și migrărilor finale, este important să existe un mediu convenabil pentru dezvoltarea regulilor (scripturilor) pentru transformarea datelor și un mediu pentru conversia datelor sursă în date pentru încărcare.

Cerințele pentru acest mediu includ:

· Comoditatea și viteza de dezvoltare a regulilor de transformare;

· Viteza de conversie a datelor. Fișierele de intrare și de ieșire pot avea sute de mii de linii!

· Abilitatea de a lucra cu mai multe fișiere de intrare simultan;

· Abilitatea de a salva regulile de transformare în fișiere separate.

Pentru proiectele noastre de migrare, am dezvoltat o stație de lucru specializată pentru dezvoltatori, folosind ca bază procesarea standard 1C Query Console.

Procesarea Consolei de interogări a fost îmbunătățită pentru a permite interogări directe către fișierele xls.

Iată un exemplu de combinare a două fișiere xls sursă Angajații.xls


Codul angajatilor

Nume de familie

Nume

Nume de familie

Data nașterii

2423

Ivanov

Ivan

Ivanovici

17.11.1992

1523

Petrov

Busuioc

Aleksandrovici

04.02.1991

4363

Sidorov

Kirill

Nikolaevici

01.05.1995

Denisov

Denis

Denizovici

01.01.1990

Și Operațiuni.xls cu pagini:

Anulări de datorii

Codul angajatilor

Data

Sumă

2423

01.02.2014

1523

02.02.2014

4363

03.02.2014

04.02.2014

100000

2423

05.02.2014

1523

06.02.2014

4363

07.02.2014

2356

08.02.2014

140000

2423

09.02.2014

1523

10.02.2014

4363

11.02.2014

23523

12.02.2014

80000

Și Chitanțe:

Codul angajatilor

Data

Sumă

01.05.2004

02.05.2004

03.05.2004

04.05.2004

2423Data nașterii

Suma chitanței

Suma anulată

Ivanov Ivan Ivanovici

2423

17.11.1992

1341234

1010

Petrov Vasili Alexandrovici

1523

04.02.1991

245245

Denisov Denis Denisovici

01.01.1990

380000

320000

Sidorov Kiril Nikolaevici

4363

01.05.1995

613382

26336

TOTAL:

2579861

347842

Rețineți că exemplul este artificial, special selectat pentru a demonstra toate etapele posibile de transformare a surselor de date.

Secvența tehnologică a operațiilor de transformare aici este următoarea:

Folosind limbajul de interogare Access SQL (care oferă capacități suplimentare semnificative în comparație cu limbajul de interogare 1C), este creată o interogare inițială care extrage datele din fișierul xls în mediul 1C. În același timp, în această etapă sunt deja posibile diverse verificări și normalizare a datelor.

Tehnologia de acces la date ADO oferă viteză mare.

Orez. 3

2. Interogare în limbajul 1C - interogarea principală care implementează algoritmul de mapare a câmpurilor. Și, de asemenea: îmbogățirea datelor descărcate cu date din baza de date 1C, regrupare, fuzionare cu rezultatele interogărilor la alte fișiere xls sursă etc.

3. Post-procesarea rezultatului cererii 1C, dacă este necesar. Implementat folosind un script în limbajul 1C.

De exemplu, aici implementăm adăugarea liniei „TOTAL” în coloanele de sumă.

4.Scrieți setul de date final într-un fișier xls.

În general, rezultatul este fișierele finale pentru încărcare în baza de date țintă 1C.

Acest instrument vă permite, de asemenea, să salvați regulile de conversie a datelor într-un fișier xml separat:

În plus, este posibil să lucrezi V modul lot, care este deosebit de important atunci când există o cantitate mare de date de migrare eterogene.

În etapele anterioare, partea pregătitoare a lucrării se încheie în general - toate sursele de date sunt identificate, datele sursă sunt descărcate din surse, șabloane de descărcare sunt pregătite în baza de date țintă, maparea datelor este pregătită și, în final, sunt dezvoltate scripturi de transformare a datelor. .

Trebuie remarcat faptul că, înainte de migrarea finală, cu siguranță ar trebui să efectuați mai multe teste. În timpul migrărilor de testare, Antreprenorul, împreună cu Clienții, identifică:

Erori de conversie, erori de încărcare a datelor

Efectuați o evaluare preliminară a calității datelor încărcate în sistemul țintă

Pe baza rezultatelor migrărilor de testare, aceștia creează/actualizează un plan final de migrare

7. Reconcilierea datelor

Calitatea datelor descărcate trebuie verificată atât după migrarea testului, cât și la sfârșitul migrării finale. În timpul reconcilierii, pot fi verificați următorii indicatori:

· Coincidența sumelor totale pentru solduri, conform documentelor;

· Potriviri cantitative, de exemplu numărul de sisteme de operare;

· Completarea corectă a entităților individuale selectate;

Vă rugăm să rețineți că anumite verificări ale datelor de migrare și problemele de normalizare a datelor trebuie rezolvate pe parcursul tuturor proceselor de migrare. Trebuie să vă întrebați întotdeauna ce trebuie făcut în etapa actuală pentru a evita greșelile în etapele ulterioare.

De exemplu:

· Verificați dacă există duplicate după câmpurile cheie. Poate și trebuie efectuată pe datele originale;

· Coercirea tipurilor de câmp;

· Integritate referenţială;

· Incoerențe matematice. De exemplu, verificarea câmpurilor numerice goale în care este planificată divizarea în timpul transformării;

· În general, verificarea câmpurilor obligatorii sunt completate;

· Înlocuirea caracterelor incorecte. De exemplu, caractere englezești în câmpurile chirilice („o”, „a”, „e”, etc.) Acest lucru este valabil mai ales pentru câmpurile cheie!

· Verificarea valorilor câmpurilor șirurilor de caractere pentru conformitatea cu tipurile de sistem de recepție (Restricții de lungime)

După ce migrarea finală este finalizată, în conformitate cu o strategie de migrare predeterminată și un plan de migrare, se ia o decizie privind funcționarea ulterioară a sistemelor istorice.

Adesea operațiunea se finalizează imediat după reconcilierea finală a datelor și înregistrarea succesului migrației - utilizatorii noului sistem nu mai țin înregistrări în două sisteme în paralel, ci trec complet la noul sistem. În același timp, accesul la vechiul sistem este menținut în modul citire.

În unele cazuri, operarea în paralel a două sisteme poate avea loc pe durata operațiunii de probă (TE) și chiar și după această perioadă. Problema muncii paralele a utilizatorilor din două sisteme este strâns legată de problema posibilității de a reveni la vechiul sistem dacă migrarea (sau, în general, funcționarea noului sistem!) este considerată nesatisfăcătoare.

Concluzie

În concluzie, aș dori să remarc că atunci când vine vorba de migrarea sistemelor tranzacționale mari, care includ multe configurații 1C:Enterprise, trecerea la un sistem nou poate fi foarte laborioasă.

Prin urmare, trebuie amintit că orice astfel de proiect necesită o pregătire atentă și trebuie să fie însoțit de un plan individual. Cu toate acestea, indiferent de tipul de sisteme migrate, de volumele bazei de date etc., schema generală de migrare arată aproape identică.

Depozit de date pentru instituție financiară

Depozitele de date din industria bancară sunt concepute pentru a consolida date disparate din sisteme disparate și pentru a extrage informații din datele consolidate. În timp ce un depozit poate rezolva problemele de consolidare a datelor, nu poate rezolva în mod magic toate problemele de informare. Formarea și gestionarea unui proiect de depozit de date bancare necesită eforturi conștiente din partea tuturor părților interesate.

În acest sens, merită să aruncăm o privire asupra pașilor (care pot fi parveniți chiar înainte de implementarea modelului de date) pentru a asigura crearea unui mediu ideal pentru implementarea cu succes a unui depozit de date într-o bancă.

1. Identificarea părților interesate în funcție de business-ul băncii (retail banking, corporate business, carduri de credit etc.).

Părțile interesate trebuie să aibă cunoștințe relevante. Pentru a înțelege mai bine depozitul de date și nevoile sale pentru fiecare funcție individuală de afaceri, este necesar să includeți membri atât din partea de business, cât și din partea tehnologiei de afaceri a echipei de proiect. Părțile interesate trebuie să fie implicate în proiect încă de la început pentru a evita scurgerile de informații în cadrul grupurilor.

2. Sesiuni de instruire pentru a înțelege necesitatea stocării datelor într-o bancă.

Părțile interesate ale proiectului ar trebui să înțeleagă că un depozit de date este un depozit pentru doar elementele de date relevante, și nu o copie exactă a sistemului sursă. Acest lucru ajută echipele să decidă ce date merită stocate.

3. Înțelegerea conceptului de modelare a datelor.

Înțelegerea utilizării tabelelor de metadate și a tabelelor istorice oferă echipei de proiect încredere că cerințele lor vor fi implementate în modelul de date.

4. Descoperirea colectivă a peisajului sistemelor sursă.

Asigurați-vă că fiecărui sistem din organizație i se acordă atenția cuvenită și luarea în considerare pentru includerea în depozitul de date.

5. Construirea unui proiect în jurul unui model de bază pentru a înțelege abordarea generală a extinderii modelului de date.

Modelul de bază ar trebui să acopere dimensiunile cheie la nivelul întregii afaceri și să ofere o perspectivă asupra datelor reale care ar putea trebui stocate.

6. Maparea datelor.

a) Maparea datelor de la sursă (sisteme sursă din organizație) la structura țintă (model de date depozit).

Trebuie să definiți sistemele sursă și relațiile dintre sisteme pentru fiecare dimensiune din modelul de date.

b) Maparea datelor pentru fiecare funcție cu membrii echipei de afaceri și IT:

Această mapare poate fi necesară la două niveluri:

Maparea directă din sistemele sursă: Majoritatea elementelor de date vor fi mapate direct în modelul de date. Aici va trebui să definiți sursa și numele câmpurilor.

Mapare derivată din sistemele sursă: unele elemente de date din model pot necesita aplicarea unor reguli de afaceri la datele sistemului sursă pentru a obține informații exacte. Ele trebuie să fie clar documentate.

La cartografierea din două sau mai multe surse, relațiile dintre aceste sisteme sursă trebuie determinate.

7. Definiţia Aggregation.

Unul dintre scopurile creării unui depozit de date este obținerea de informații analitice din datele istorice. De asemenea, implică construirea de tendințe predictive din date. Agregarea definește straturile sau dimensiunile în care sunt analizate datele. Cel mai bine este ca agregarile să fie definite pe baza informațiilor (rapoarte și tablouri de bord) care trebuie obținute din modelul de date.

8. Omiterea și denumirea elementelor de date.

Echipele de proiect trebuie să accepte că sursa nu poate furniza întotdeauna toate datele într-un model standard. Membrii echipei trebuie să decidă fie să excludă aceste elemente din model, fie să le părăsească, dar să nu le folosească. Modul preferat este să omiteți câmpurile irelevante. Acestea ar trebui să rămână neutilizate numai atunci când se preconizează că vor fi utile în viitor.

9. Declarație privind îmbunătățirea ulterioară a procesului.

Deși depozitele de date în sine nu sunt un proiect de îmbunătățire a procesului, ele pot aduce îmbunătățiri dincolo de depozitul în sine. Punctele slabe observate în procese sau sisteme sursă ar trebui notate și abordate în paralel. Cu toate acestea, modificările aduse de proces pot fi făcute ulterior și nu ar trebui să afecteze proiectul depozitului de date.

10. Alinierea versiunii.

Modelele de cartografiere și de date ar trebui acceptate ca versiuni, legate de modificări pe măsură ce proiectul evoluează. Este important să se creeze un proces menit să se adapteze la aceste schimbări.

A avea prea multe date de stocat și analizat poate fi o provocare pentru fiecare organizație, mai ales când duce la inconsecvențe în valori. Când există prea multe date, trebuie să vă ocupați de datele conflictuale din rapoarte, să alegeți între indicatorii conflictuali și să ștergeți înregistrările duplicate. Acest lucru necesită prea mult timp și resurse, în special în cele mai mari companii care au implementat prea multe depozite de date sau marturi de date care oferă informații diferite despre aceleași procese sau evenimente de afaceri.

Atât instituțiile bancare, cât și întreprinderile din sectorul real al economiei trebuie să rezolve această problemă. Apelând la experiența lor, puteți obține mai multe recomandări universale.

Reduceți mai multe depozite de date la o singură instanță

Boeing a trecut prin acest proces, începând cu 12 depozite de date și 50 de sisteme de management al costurilor, dintre care unele aveau zeci de mii de reguli de afaceri. „Problema era că departamentul nostru IT a furnizat utilizatorilor ceea ce aveau nevoie, dar ei nu comunicau între ei”, spune Bill Curley, director financiar Boeing. Această lipsă de integrare a fost cauza inconsecvențelor în raportare.

Boeing a avut nevoie de câțiva ani pentru a-și consolida toate situațiile financiare într-un singur întreg. Membrii echipei de proiect care lucrează la această sarcină au adoptat o abordare de sus în jos - i-au întrebat pe „proprietarii de date” de ce informații au nevoie pentru a face treaba și au implementat un dicționar de date standard cu elementele minime necesare. În plus, au separat datele contabile operaționale și efective necesare pentru raportare. „Nu mai aveam nevoie să rulăm informații operaționale prin sistemul nostru de contabilitate”, spune Bill Curley.

Trecerea la o arhitectură de date unificată pentru a îmbunătăți calitatea datelor

Nike a lucrat la această sarcină în ultimii ani. Pentru a face acest lucru, arhitectul de date al companiei, James Lee, a eliminat datele duplicate, a completat câmpurile lipsă din tabele și s-a ocupat de o serie de rapoarte care au durat prea mult să fie generate. „Pe calea către o singură versiune a adevărului, ne-am dorit să obținem o flexibilitate semnificativă, astfel încât unitățile de afaceri să-și poată genera rapoartele fără participarea departamentului IT. Unul dintre obiective a fost ca utilizatorii să fie autosuficienți în ceea ce privește lucrul cu date”, își amintește el. Unul dintre cele mai des folosite tabele Nike conținea peste o sută de coloane. Acest lucru a fost extrem de ineficient în ceea ce privește I/O și utilizarea puterii de procesare. Nike a simplificat acest tabel ultra-larg și și-a redus modelele de date la mai puține elemente. Acest proces a îmbunătățit, de asemenea, calitatea datelor, făcând utilizatorii responsabili pentru elementele de date lipsă, dar necesare și devenind mai proactivi în urmărirea acestora.

Publicaţii

  1. Aarti Nyadish. „Proiectul ideal pentru depozitarea datelor bancare: 10 pași pentru stabilirea ritmului potrivit”, 15 ianuarie 2013.
  2. David Strom. „Coping with Too Much Data: How Boeing, Nike and Others Did It”, 23 octombrie 2012.