Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Schimbare adresa DNS IPv4 pe rout...

Recomandare Barebone

Monede JO 2024

Suprasolicitare sistem electric
 CIV auto import

Mutare in MOZAMBIC - pareri, expe...

Scoatere antifurt airtag de pe ha...

Magnet in loc de clește pent...
 Cumparat/Locuit in apartament si ...

Pot folosi sistemul PC pe post de...

Sokol cu distorsiuni de cross-over

Filtru apa potabila cu osmoza inv...
 Kanal D va difuza serialul “...

Upgrade xiaomi mi11

securitate - acum se dau drept - ...

Farmacia Dr Max - Pareri / Sugest...
 

update statusId in baza de date?

- - - - -
  • Please log in to reply
17 replies to this topic

#1
AlleXyS1

AlleXyS1

    Active Member

  • Grup: Members
  • Posts: 1,107
  • Înscris: 05.05.2010
Incerc sa aflu care metoda este mai viabila si "loveste" mai putin baza de date cu verificari inutile, doar ca, nu imi dau seama.

Am o tabela Anunturi (Sql Server), cu doi parametri ce reprezinta subiectul: statusId si CreatedDate

Cand se creeaza un nou anunt, vine cu statusId = 1 (activ) si CreatedDate = DateTime.Now (c#, dar nu prea are importanta limbajul in situatia asta)

Vreau ca, dupa o saptamana de la CreatedDate, statusId sa devina 2 (inactiv, adica anuntul sa fie valabil fix 7 zile)

Cum pot face asta intr-un mod cat mai performant?

- 1. pot pune formula pe tabela si sa uit de ea, iar daca dau delete database si fac migrare din nou, s-a dus la naiba, ca sigur uit de ea
- 2. pot crea o metoda in API de genul checkStatus() care sa updateze statusul si sa o execut la fiecare request primit de API din partea clientului, cand este vizualizata lista anunturilor, sau un anunt in particular. Problema aici e, ca pe langa requestul primit de server pentru afisarea listei sau a anuntului (adica actiune in baza de date),  o sa mai fie un request in plus pentru verificarea tuturor anunturilor din tabela ce au statusId = 1, adica, da ca nesimtitul in baza. Si daca ne gandim ca ar fi 1000 vizitatori pe site care vor sa vada un anunt, inseamna 1000 verificari mai mult ca sigur inutile a metodei checkStatus()
- 3. daca metoda de la pct 1) este singura solutie, as putea adauga formula cu ajutorul migratiei/DbBuilderului?

intr-o metoda ar fi destul de simplu ceva de genul :

if (CreatedDate.AddDays(7) >= DateTime.Now) StatusId = 2;

dar cum fac verificarea asta pentru toate liniile din tabela? ma gandesc ca ar trebui executata in permanenta si asta ar solicita destul de mult.

#2
neagu_laurentiu

neagu_laurentiu

    Guru Member

  • Grup: Senior Members
  • Posts: 40,603
  • Înscris: 30.07.2003
UPDATE tabela SET camp=valoare WHERE conditie

Iar asta o poti automatiza din SQL la un anumit timp, nu trebuie sa te legi de clienti.

Edited by neagu_laurentiu, 30 June 2018 - 14:28.


#3
_Smiley_

_Smiley_

    Guru Member

  • Grup: Senior Members
  • Posts: 20,032
  • Înscris: 24.02.2006
ai o gramada de optiuni:
-poti pune un job/task in SQL Server Agent, care sa actualizeze periodic (zilnic) inregistrarile din baza
-poti accesa inregistrarile prin intermediul unui view, care sa-ti calculeze automat (on the fly) coloana status

varianta cu metoda apelata la fiecare request este cea mai proasta, pentru ca-ti va irosi o gramada de resurse

ca si recomandare generala, ai grija cu coloanele DateTime. in foarte multe cazuri componenta de timp o sa-ti cauzeze necazuri.

#4
danvlas

danvlas

    Guru Member

  • Grup: Senior Members
  • Posts: 11,118
  • Înscris: 04.06.2009
E o valoare calculata. De ce ai vrea sa o stochezi in baza de date?
Case when DateAdd(day,  7, CreatedDate) >= GetDate() Then 2 else 1 end As Status

#5
Mosotti

Mosotti

    Geniu umil

  • Grup: Senior Members
  • Posts: 33,295
  • Înscris: 21.04.2004
Poate statusul nu depinde doar de data, de exemplu poate fi setat de un user care nu mai vrea sa primeasca telefoane dupa ce si-a vindut sandramaua...

#6
AlleXyS1

AlleXyS1

    Active Member

  • Grup: Members
  • Posts: 1,107
  • Înscris: 05.05.2010

 neagu_laurentiu, on 30 iunie 2018 - 14:09, said:

UPDATE tabela SET camp=valoare WHERE conditie
Iar asta o poti automatiza din SQL la un anumit timp, nu trebuie sa te legi de clienti.

hm, da ... as putea face o procedura care sa se execute o data la 24 ore, de exemplu la ora 04:00 cand inactivitatea este mai mare (am vazut ca se practica si pe alte siteuri chestia asta). Dar asta ar crea un delay.... adica, daca in mod normal un anunt ar trebui dezactivat la ora 18:00, asta nu se va intampla atunci, ci abia dupa 10 ore, cand procedura va fi executata la ora 04:00

 Mosotti, on 30 iunie 2018 - 17:13, said:

Poate statusul nu depinde doar de data, de exemplu poate fi setat de un user care nu mai vrea sa primeasca telefoane dupa ce si-a vindut sandramaua...

da, nu depinde doar de data, userul isi poate inactiva anuntul, sau chiar administratorul il poate inactiva, arhiva, modera. Cam astea ar fi actiunile. Dar as fi vrut ca fara interventie (user, administrator), dupa o anumita perioada, anuntul sa se inactiveze automat fara sa rup baza ... tinand cont ca trebuie sa verifice toata lista ar fi ceva de genul :

update announces set statusId = 2 where (DATEADD(day, 7, CreatedDate) = getdate()) // cred ca asa ar fi..dar asta tot ar insemna ca verificarea se face tot timpul.

Cred ca cea mai buna solutie ar fi cum spune neagu_laurentiu, chiar daca poate exista un delay de 23:59 ore (maxim)

Edited by AlleXyS1, 30 June 2018 - 18:12.


#7
neagu_laurentiu

neagu_laurentiu

    Guru Member

  • Grup: Senior Members
  • Posts: 40,603
  • Înscris: 30.07.2003
Da' n-ai decat sa o pui la fiecare ora sau fa un select distinct la ce nivel de perioada ai chef. Totul e sa ai un index pe acea conditie si va zbura update-ul.

Edited by neagu_laurentiu, 30 June 2018 - 18:16.


#8
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,236
  • Înscris: 24.02.2007

 AlleXyS1, on 30 iunie 2018 - 18:07, said:

daca in mod normal un anunt ar trebui dezactivat la ora 18:00, asta nu se va intampla atunci, ci abia dupa 10 ore, cand procedura va fi executata la ora 04:00

Nu te opreste nimeni pe langa acel UPDATE periodic sa pui mereu si o conditie in SELECT pentru a fi sigur ca nu ceri anunturi expirate.

Daca vorbim de performanta, trebuie facute masuratori in scenarii adecvate. Conteaza cat de multe inregistrari sunt, cata memorie e disponibila (pentru caching), cat de rapid e discul, etc.

Edited by dani.user, 30 June 2018 - 18:26.


#9
romio79

romio79

    Active Member

  • Grup: Members
  • Posts: 1,655
  • Înscris: 30.03.2005
Nu prea ai de ce sa faci update, exceptie e doar cand anuleaza userul anuntul

In selectul care aduce anunturile pui cinditia pe data

#10
WinstonMontana

WinstonMontana

    Active Member

  • Grup: Members
  • Posts: 1,913
  • Înscris: 20.02.2018

 AlleXyS1, on 30 iunie 2018 - 14:01, said:

Cand se creeaza un nou anunt, vine cu statusId = 1 (activ) si CreatedDate = DateTime.Now (c#, dar nu prea are importanta limbajul in situatia asta)
Vreau ca, dupa o saptamana de la CreatedDate, statusId sa devina 2 (inactiv, adica anuntul sa fie valabil fix 7 zile)

update statusId = 2 from dbo.Anunturi where datediff(day,cast(CreatedDate as date), getdate()) > 7


Quote

),  o sa mai fie un request in plus pentru verificarea tuturor anunturilor din tabela ce au statusId = 1,
pune-ti indecsi pe coloanele din tabela care sunt utilizate la greu sau intra in componenta cheiei de business

 _Smiley_, on 30 iunie 2018 - 14:29, said:

ca si recomandare generala, ai grija cu coloanele DateTime. in foarte multe cazuri componenta de timp o sa-ti cauzeze necazuri.
in ce sens necazuri, dezvolta te rog afirmatia.

Quote

de exemplu la ora 04:00 cand inactivitatea este mai mare (am vazut ca se practica si pe alte siteuri chestia asta).
Da , i se spune  "job".

Quote

Dar asta ar crea un delay.... adica, daca in mod normal un anunt ar trebui dezactivat la ora 18:00, asta nu se va intampla atunci, ci abia dupa 10 ore, cand procedura va fi executata la ora 04:00
Bun venit in enterprise realm: joburi , dependinte de joburi, si orar de joburi (adica acel delay)

 danvlas, on 30 iunie 2018 - 16:31, said:

E o valoare calculata. De ce ai vrea sa o stochezi in baza de date?
pentru ca tabela sa este de tip log/istoric cel mai probabil

Edited by WinstonMontana, 30 June 2018 - 20:50.


#11
Mosotti

Mosotti

    Geniu umil

  • Grup: Senior Members
  • Posts: 33,295
  • Înscris: 21.04.2004
Indexul pe cimpul ala nu ajuta la nimic, ar trebui un bitmap index, daca SQL server are asa ceva...

#12
_Smiley_

_Smiley_

    Guru Member

  • Grup: Senior Members
  • Posts: 20,032
  • Înscris: 24.02.2006

 WinstonMontana, on 30 iunie 2018 - 20:48, said:

 _Smiley_, on 30 iunie 2018 - 14:29, said:

ca si recomandare generala, ai grija cu coloanele DateTime. in foarte multe cazuri componenta de timp o sa-ti cauzeze necazuri.
in ce sens necazuri, dezvolta te rog afirmatia.
in foarte multe situatii acolo vrei de fapt sa salvezi o data, fara partea de timp. si daca pui acolo datetime, ulterior va trebui sa te tot chinui sa extragi data din datetime pentru diverse comparatii
aici nu pare sa fie cazul, dat fiind ca a mentionat ca anunturile pot expira la ora 6 (deci chiar are nevoie si de timp).

#13
danvlas

danvlas

    Guru Member

  • Grup: Senior Members
  • Posts: 11,118
  • Înscris: 04.06.2009

 AlleXyS1, on 30 iunie 2018 - 18:07, said:

update announces set statusId = 2 where (DATEADD(day, 7, CreatedDate) = getdate()) // cred ca asa ar fi..dar asta tot ar insemna ca verificarea se face tot timpul.
Conditia aia se va indeplini doar printr-un noroc chior. As putea zice ca nu se va indeplini niciodata. Getdate() iti da ceva de genul 2018-06-30 12:35:56.091
In continuare sunt convins ca o valoare calculata prin orice formula nu trebuie stocata in baza de date. O singura exceptie: valoarea respectiva intra intr-un index, de preferinta unic.

#14
AlleXyS1

AlleXyS1

    Active Member

  • Grup: Members
  • Posts: 1,107
  • Înscris: 05.05.2010

 danvlas, on 01 iulie 2018 - 12:11, said:

In continuare sunt convins ca o valoare calculata prin orice formula nu trebuie stocata in baza de date. O singura exceptie: valoarea respectiva intra intr-un index, de preferinta unic.

te referi la faptul ca n-ar trebui sa stochez statusul in baza de date? si as putea avea ceva de forma CreatedDate, InactivatedDate si as avea metodele:

get(int id) {
entity = context.Announces.Where(p => p.Id == id).FirstOrDefault();
entity.Status = entity.InactivatedDate > DateTime.Now ? ''inactiv" : "activ"; // (sa verific statusul de fiecare data cand este cerut anuntul)
}


// doar anunturile active
getAll() {
entities = context.Announces.Where(p => p.InactivatedDate < DateTime.Now).ToList(); // sa am conditia asta tot timpul cand vreau sa returnez o lista de anunturi active
}


credeam ca asta o sa-mi creeze probleme daca vreau mai multe actiuni pe anunt din partea adminului, cum am spus mai sus (inactiva in orice moment [asta inseamna un update pe linia din tabela din partea adminului, "UPDATE announce SET InactivatedDate = getDate()"] si parca n-ar mai rupe atat de rau baza de date), dar ce am scris in paranteza pare o solutie buna, venita pe moment Posted Image) si acum imi dau seama si de ce .... nici la locul de munca, in DB nu gasesc valori calculate prin formule cum spui tu (dinamice, modificabile in functie de timp sau alte formule, cum le spun eu), ci le gaseam prin codul aplicatiei (enum listuri in general) si chiar ma enerva chestia asta, ca nu pot pastra o evidenta mai clara asupra entitatilor Posted Image)

deci, decat o formula care sa se execute tot timpul, un task, un view sau o procedura (de care cel mai sigur o sa uit, si la urmatorul drop-database, update-database nu o sa stiu de ce imi aduce anunturi aiurea), mai bine o coloana InactivatedDate in tabela. Pentru ca o verificare pe entitati aveam si inainte (WHERE statusId = 1), acum o sa fie (WHERE InactivatedDate < DateTime.Now)

asta daca am inteles bine fiecare reply in parte Posted Image)

singura chestie ce nu imi place e ca in metoda getAll(), daca vreau sa aduc si statusul odata cu lista anunturilor, va trebuie sa ma folosesc de un foreach cu atribuirea statusului pentru fiecare item in parte (ca in cazul get() ).

getAll() {
   entities = context.Announces.Where(p => p.InactivatedDate < DateTime.Now).ToList(); // sa am conditia asta tot timpul cand vreau sa returnez o lista de anunturi active
   foreach(item in entities) {
	  item.Status = entity.Status = entity.InactivatedDate > DateTime.Now ? ''inactiv" : "activ";
   } 
}


multumesc

Edited by AlleXyS1, 01 July 2018 - 13:10.


#15
danvlas

danvlas

    Guru Member

  • Grup: Senior Members
  • Posts: 11,118
  • Înscris: 04.06.2009
Vorbim de o baza de date. Asta contine obiecte, ca 0tabele, view-uri, proceduri stocate, functii.
Eu n-as pune clientul (C#, VB, Delphi samd) sa execute interogari pe tabele, ci l-as pune sa apeleze obiectele bazei de date.
View-ul sau procedura stocata se pot modifica dupa dorinta pe serverul SQL, iar aplicatia va ramane neschimbata.
Atentie mare la securitatea bazei de date. Daca permiti aplicatiei client sa scrie sau sa stearga prin baza de date, permiti implicit userilor care stiu contul si parola sa execute operatiunile prin orice metoda doresc fara sa-i detectezi in aplicatie.
Editarile, adaugarile si stergerile din baza de date se fac NUMAI cu proceduri stocate.

#16
_Smiley_

_Smiley_

    Guru Member

  • Grup: Senior Members
  • Posts: 20,032
  • Înscris: 24.02.2006
de aproape un deceniu s-a cam trecut la linq si entity framework Posted Image

@AlleXyS1: vezi ca toate clasele generate automat de EF sunt cu partial, deci le poti extinde prin adaugarea unor proprietati calculate. e mult mai ok sa adaugi o proprietate calculata decat sa o calculezi tu manual la fiecare incarcare a datelor

Edited by _Smiley_, 01 July 2018 - 16:34.


#17
AlleXyS1

AlleXyS1

    Active Member

  • Grup: Members
  • Posts: 1,107
  • Înscris: 05.05.2010

 danvlas, on 01 iulie 2018 - 16:10, said:

Editarile, adaugarile si stergerile din baza de date se fac NUMAI cu proceduri stocate.

Posted Image Posted Image  asta n-o pricep.

 _Smiley_, on 01 iulie 2018 - 16:25, said:

de aproape un deceniu s-a cam trecut la linq si entity framework Posted Image

daca la comentariul lui te refereai, inteleg ... folosesc EF Core, ce vine la pachet cu Asp.Net Core 2. aplicatia este de tip Web API (asp.net) + Client (Angular 6)

 danvlas, on 01 iulie 2018 - 16:10, said:

Atentie mare la securitatea bazei de date. Daca permiti aplicatiei client sa scrie sau sa stearga prin baza de date, permiti implicit userilor care stiu contul si parola sa execute operatiunile prin orice metoda doresc fara sa-i detectezi in aplicatie

credeam ca Entity Framework rezolva problema securitatii. Prin user care stie contul si parola te referi la generarea unui token valid, si pe baza acestuia sa trimita requesturi catre API din afara aplicatiei Client (gen Postman) de modificare a bazei de date?

#18
WinstonMontana

WinstonMontana

    Active Member

  • Grup: Members
  • Posts: 1,913
  • Înscris: 20.02.2018

 AlleXyS1, on 01 iulie 2018 - 16:36, said:

credeam ca Entity Framework rezolva problema securitatii. Prin user care stie contul si parola te referi la generarea unui token valid, si pe baza acestuia sa trimita requesturi catre API din afara aplicatiei Client (gen Postman) de modificare a bazei de date?
chestia asta o poate face spring jdbc via spring security, module ale lui spring framework

Anunturi

Chirurgia cranio-cerebrală minim invazivă Chirurgia cranio-cerebrală minim invazivă

Tehnicile minim invazive impun utilizarea unei tehnologii ultramoderne.

Endoscoapele operatorii de diverse tipuri, microscopul operator dedicat, neuronavigația, neuroelectrofiziologia, tehnicile avansate de anestezie, chirurgia cu pacientul treaz reprezintă armamentarium fără de care neurochirurgia prin "gaura cheii" nu ar fi posibilă. Folosind tehnicile de mai sus, tratăm un spectru larg de patologii cranio-cerebrale.

www.neurohope.ro

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate