Ett intressant problem... jag har använt ett script med delete from för att ta bort användare som inte återkommit på 90 dagar (kan visa koden senare när jag kommer hem och har tillgång till den). Datan försvann som den skulle, jag har dels testat några egna testanvändare och sett att de är borta, dels kollat i databasen i phpMyAdmin, och delt gjort en backupfil med MySQL Admin programmet på datorn där jag sett att databasen minskat från tidigare 6,7 MB till nu ca 4MB. Kundzonen på loopia, mitt webbhotell, säger dock att databasen inte är 6.7 som tidiagare, och inte drygt 4 som min backupfil (som tidigare stämt överens storleksmässigt) säger, utan den har på loopias utrymme växt till öve 8MB.. hur är detta möjligt? Vad har jag missat? Det är väl troligen så att även om du raderat poster så finns det utrymme kvar reserverat för dem. Vet inte hur det riktigt fungerar, men du måste i alla fall optimera databasen (som du kan göra genom MySQL Administrator). Den borde då sjunka till mindre storlek. Jag tog ditt råd och försökte köra en optimize table genom MySQL Administrator men fick följande fel om det är mycket data som ändras (läggs till och tas bort) så kan utrymme finnas kvar på något sätt. Felet verkar helt enkelt att du inte har rättigheter att utföra optimeringen. Kanske finns andra sätt att göra det på, vet faktiskt inte. Jag fixade det där med optimeringen. Jag hade som du sa inga rättigheter att utföra operationen när jag körde från MySQL Administrator men när jag loggade in på webbgränssnitett från Loopia hade jag rättigheten (IP-nummer baserad kanske). Här är en länk till en utförlig beskrivning på foreign keys och constraints: http://dev.mysql.com/doc/refman/4.1/en/innodb-foreign-key-constraints.html ON UPDATE CASCADE är användbart när du har naturliga nycklar så som username. Om du har en auto inkrimenterande integer så är det väldigt sällan du uppdaterar värdet. Som en liten upprättelse för Loopia =) versionen är 4.1.21, inte såå föråldrad alltså antar jag. Nä, men med tanke på att version 5.0 är i produktions stadiet, version 5.1 är i beta stadiet och version 6 i alpha stadiet så är det nog lite föråldrat. Det bästa vore om du skulle få tillgång till version 5.0, men det fungerar som sagt bra med den versionen Loopia har nu.delete from ...
Sv: delete from ...
Sv:delete from ...
Error - Table `hemekonomi_com`.`budget` could not be optimized.
MySQL Error Nr.1044
Access denied for user 'remoteadmi@h4332'@'%' to database 'hemekonomi_com'
Så här ser förresten koden ut... give it to me, berätta precis hur sunkig den är ;-) Jag vill gärna lära mig göra bättre, jag har ju liksom bara lärt mig genom trial and error, och läst på när det behövts, jag har aldrig satt mig ner och tagit reda på hur man "ska" göra =)
<% @ CODEPAGE = 1252 %>
<% server.ScriptTimeout=9999999 %>
<!-- #include file="conn.asp" -->
<%
Set Rs = Server.CreateObject("ADODB.Recordset")
IF NOT session("user")=45 THEN response.redirect "default.asp" END IF
rs.open "SELECT `user` FROM users WHERE `last`<'" & date-90 & "' AND `user` NOT IN (1,45) ORDER BY `user`",Conn
Do until rs.EOF
'rensa budget
Set Rs2 = Server.CreateObject("ADODB.Recordset")
rs2.open "SELECT `id` FROM kategorier WHERE user=" & rs("user"),Conn
do until rs2.EOF
sql="DELETE FROM budget WHERE kategori=" & rs2("id")
conn.execute sql
rs2.MoveNext
loop
rs2.Close
set rs2 = nothing
'rensa kategorier
sql="DELETE FROM kategorier WHERE user=" & rs("user")
conn.execute sql
'rensa favoriter
sql="DELETE FROM favoriter WHERE user=" & rs("user")
conn.execute sql
'rensa fodelsedagar
sql="DELETE FROM fodelsedagar WHERE user=" & rs("user")
conn.execute sql
'rensa kalender
sql="DELETE FROM kalender WHERE user=" & rs("user")
conn.execute sql
'rensa kassabok
sql="DELETE FROM kassabok WHERE user=" & rs("user")
conn.execute sql
'rensa kontakt
sql="DELETE FROM kontakt WHERE user=" & rs("user")
conn.execute sql
'rensa rakningar
sql="DELETE FROM rakningar WHERE user=" & rs("user")
conn.execute sql
'rensa share
sql="DELETE FROM share WHERE sharer=" & rs("user")
conn.execute sql
'rensa vanner
sql="DELETE FROM vanner WHERE user=" & rs("user")
conn.execute sql
response.flush
Rs.movenext
i=i+1
loop
rs.close
set rs = nothing
'rensa users
sql="DELETE FROM users WHERE `last`<'" & date-90 & "' AND `user` NOT IN (1,45)"
conn.execute sql
response.Write i & " users deleted together with their contents " & now
conn.close
set conn = nothing
%>Sv: delete from ...
Man kan optimera tabeller där data ändras mycket.
OPTIMIZE TABLE `tbl__articles`;Sv: delete from ...
Angående din kod tycker jag, efter en snabb blick på den, inte att det ser dåligt ut.
Men saker jag kan anmärka på är:
1. "server.ScriptTimeout=9999999": Troligen inte är det smartaste att göra. En timeout finns där för att avbryta körningen om något går fel i koden, till exempel oändliga loopar etc.
2. session("user")=45: Skulle i vissa fall kunna gå fel även om du har 45 i session("user"). En kontroll om isnumeric(session("user")) och sedan en if cint(session("user")) = 45 ...
3. Du har mycket att vinna i prestanda och förenkling av kod om du arbetar om databasen lite. Visst kör du MySQL? Vilken version? Som jag tidigare nämnt är det smartast att köra med Foreign Key och Constraint funktionaliteten i databasen. På detta sätt slipper du alla loopar i kod där du raderar användares inlägg från flera olika tabeller.
Som exempel, anta att du har <b>tabell_a</b> där du sparar alla dina användare med en auto_increment primary key som är unik för varje användare. Sedan har du <b>tabell_b</b> som har en egen primary key men data i denna tabell är direkt relaterad till <b>tabell_a</b>. Du kan då ha i <b>tabell_b</b> en foreign key som kopplar ihop ett fält i <b>tabell_b</b> till primary key i <b>tabell_a</b>. Sedan har du en constraint på denna foreign key som säger att när data i <b>tabell_a</b> raderas så raderas även de rader i <b>tabell_b</b> som relaterar till de raderade raderna i <b>tabell_a</b>.
Förstår du? På detta sätt kan du slippa alla extra loopar i koden och låter databasen sköta om att det inte blir data kvar att hänga som inte hör någonstans.
4. Din "rensa users" SQL kan förbättras. Testa om du kan köra med "DELETE FROM `users` WHERE `last` < NOW() - INTERVAL 90 DAY AND `user` NOT IN (1, 45)". Är användarna med id 1 och 45 administratörer? Det kan jag också påpeka lite på att det inte är det smartaste sättet att programmera på att ha det hårdkodat, men det vet du nog redan ;). Jag skulle skapa en till tabell, med Foreign Key till users, där alla användare med admin rättigheter finns (eller vad det är 1 och 45 betecknar).
Jag antar att koden tar ett tag att köra idag om det är många användare som ska raderas? Det beror som sagt på alla databasanrop som måste ske och detta skulle ta en bråkdels sekund om du designar om lite i databasen och minskar ner koden till bara några rader. Vill du ha mer hjälp eller tips är det bara att fråga ;)
Har du funderat på att gå över till ASP.NET alls? Tänkte att det kanske inte är så smart att bli expert på gammal teknik? ;)Sv:delete from ...
Timeouten satte jag bara en massa nior för att jag ville att den verkligen skulle göra klart, visste inte att det var i sekunder då =) men jo, det tog närmare 40 minuter att köra klart scriptet =)
Angående foreign key osv. låter jättebra, hur gör man =) version 3,5någonting tror jag det är.
Angående de hårdkodade så stämmer det att den ena är admin-kontot och den andra är jag själv, som iofs använde sajten regelbundet, varje vecka, men som en säkerhetsgrej att mitt inte tas bort även om jag skulle hamna på sjukan några månader =p
Tips är välkomna - hur gör jag för att implementera det där med kopplade nycklar?
Sedan när det gäller SQL, som du sett förut så har jag inte så stor koll på det utan gör det med kod.. men jag håller på att gå igenom mina databasfrågor för att optimera dem (det kommer nog upp mer under ASP-forumet snart =) ).
Jag har absolut sneglat på ASP.NET, i omgångar. Har kollat på de där 11 intro-videorna, men det varkar ju lite annorlunda tänk med det hela, och jag har inte känt att jag haft tid att sätta mig in i något nytt, men det är definitivt med på den mentala "att-göra" listan.
Men finns det inte en hel del mer att ta hänsyn till där ur säkerhetssynpunkt osv? Jag tänker att jag precis känner att jag börjat få koll på var hoten ligger (SQL injection, XSS osv.) och börjar bygga in skydd mot det... men jag har med i beräkningen att bygga om sajten till .NET framöver, när den kommit igång lite. Eller låta någon annan sköta den ombyggnationen så att det blir proffsigt gjort, även om det kostar lite.Sv: delete from ...
Att lägga till det i dina befintliga tabeller ska inte vara svårt eller invecklat. Du måste bara ändra på dem genom att lägga till index på varje fält som ska höra till en foreign key och sedan läga till själva foreign key och constraint. Länken borde beskriva det utförligt hur du gör. Men fråga om du inte kan ändå.
Version 3.5 är väldigt gammal. Kanske börjar vara dags för Loopia att uppgradera om de inte gjort det? ;)
Men när du ansluter med MySQL Administrator så borde du under "Server information" kunna utläsa vilken version det är.
Och sen när du lägger till foreign key constraints kan du också se till att lägga in ON UPDATE CASCADE så kan du uppdatera primary key värden i huvudtabellen (users) och den uppdateringen går automatiskt vidare till de andra. ON DELETE CASCADE ser sen till att "barntabellerna" raderar sina relaterade tabeller när de raderas från huvudtabellen.
Ett tips, om du inte redan har version 5 av MySQL kolla med Loopia om de har en server du skulle kunna flytta till och få köra på MySQL version 5. I version 3 och 4 verkar foreign key constraints inte vara helt utvecklat än. Men om du inte kan få MySQL 5 fungerar det nog för dig ändå.
Jag brukar använda mig av MySQL Query Browser för att skapa databasen. Det är väldigt bekvämt då man inte behöver ta hand om alla SQL satser för hand.Sv:delete from ...
Man skall vara försiktig med ON DELETE CASCADE. JAg hade en applalkiation för att lägga offerter. I den fanns det DELETE CASCADE mellan anställd och offerter. Vilket innebär att när de tog bort en anstäld så försvann alla offerter. Ett bättre alternativ hade då varit ON DELETE SET NULL.
Vilket hade gjort det möjligt att söka de offerter som var "herrelösa".
I ditt fall så verkar det som datat är hårt knyten till användaren.
Om det istället hade varit mer gemnsam information. Så som poster i ett forum, så kan det vara lämpligt att lämna kvar dem. Då trådar kan bli lite konstiga när någon svara på ett svar som är borttaget.Sv: delete from ...
Sv:delete from ...