•  
  • Archives for Maik (24)
  • Page2

größe aller Tabellen ermitteln – MSSQL

by Maik
Categories: Allgemein
Tags: No Tags
Comments: Kommentare deaktiviert
Published on: 06.08.2010
Tabellengrösse in MSSQL
Tabellengrösse MSSQL

Wenn man bei der täglichen Datensicherung so überprüft, fällt einem ab und zu ein richtig großer Brocken auf. Bei Dateien ist das kein Problem, bei Datenbanken hingegen schon. Wenn die SQL-Datenbank plötzlich mehrere Gigabyte (GB) groß ist, fragt man sich, woher das kommt. Es gibt die Möglichkeit, auf jede Tabelle zu klicken und dann
Um den Überblick über alle Tabellen und deren größte Speicherfresser in einer Datenbank zu erhalten, braucht man nur die folgende Prozedur.

CREATE PROCEDURE [dbo].[Groesse_aller_Tabellen_einer_DB]
AS
BEGIN
SET NOCOUNT ON;

declare @RowCount int, @tablename VARCHAR(100)
declare @Tables table (
PK int IDENTITY(1,1),
tablename VARCHAR(100),
processed BIT
)
INSERT INTO  @Tables (tablename)
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' and TABLE_NAME NOT LIKE 'dt%' ORDER BY TABLE_NAME asc

declare @Space TABLE (
name VARCHAR(100), rows nVARCHAR(100), reserved VARCHAR(100), data VARCHAR(100), index_size VARCHAR(100), UNUSED VARCHAR(100)
)
SELECT TOP 1 @tablename = tablename FROM @Tables WHERE processed IS NULL
SET @RowCount = 1
WHILE (@RowCount != 0)
BEGIN
insert INTO  @Space exec sp_spaceused @tablename
UPDATE @Tables set processed = 1 WHERE tablename = @tablename
SELECT TOP 1 @tablename = tablename FROM @Tables WHERE processed IS NULL
SET @RowCount = @@RowCount
END

UPDATE @Space set data = replace(data, ' KB', '')
UPDATE @Space set data = convert(int, data)/1000
UPDATE @Space set data = data + ' MB'
UPDATE @Space set reserved = replace(reserved, ' KB', '')
UPDATE @Space set reserved = convert(int, reserved)/1000
UPDATE @Space set reserved = reserved + ' MB'

SELECT * FROM @Space ORDER BY CONVERT(INT, REPLACE(data, ' MB', '')) DESC
END

MySQL Daten Sichern – automatisches Backup

by Maik
Categories: Allgemein
Tags: No Tags
Comments: No Comments
Published on: 05.08.2010

Einen Server bei einem der großen Hoster (Hetzner, 1&1 usw.) stehen zu haben ist schon toll. Man muss sich keine Gedanken um Stromkosten, Überhitzung und andere Dinge Gedanken machen. An eines sollte man aber immer denken, an die Datensicherung!
Um dies so automatisiert wie möglich zu machen, hier eine kurze Anleitung.
Als erstes müssen wir ein Backup der Datenbank machen. Dies kann man zwar auch über PhpMyAdmin versuchen, ab einer gewissen DB-Größe geht das aber schief. Außerdem ist der Mensch von Natur aus faul, deshalb hier ein Linux-Bash-Script, bzw. das Ganze gleich in die Cronjob (crontab -e) geschrieben:

# m h  dom mon dow   command
 5 0 * * * root /var/backup/backup.sh

Dieser wird täglich um 00:05 Uhr als “root” ausgeführt.
Die Datei “/var/backup/backup.sh” sieht dann ungefähr so aus:

mysqldump -ubenutzer -ppasswort -Q --all-databases > /var/backup/mysql_backup.sql
tar -zcvpf /var/backup/backup`date +%Y-%m-%d`.tar.gz /var/backup/mysql_backup.sql

Ein mysqldump mit dem angegebenen Benutzernamen, Passwort und aller Datenbanken wird nach /var/backup ablegt. Dannach wird dieser in eine Datei mit dem aktuellem Datum im Namen gezippt.
Damit die Daten auch vom Server gesichert werden können, gibt es viele Möglichkeiten. Wenn man bei sich einen Linuxserver hat, kann man auch diesen Schritt mit einem Cronjob automatisieren.

 /usr/bin/rsync -aptz -e "ssh -i /home/id_rsa" user@server:/var/backup/ /var/backup/

Dieser Job wird auf dem lokalen Server ausgeführt. Er synchronisiert unser Backup-Verzeichnis mit dem lokalen Verzeichnis und kopiert so die gesicherte Datenbank zu uns.
Das Verfahren zur automatischen Generierung eines SSH-Keys habe ich hier bereits kurz beschrieben.

Tabellenspaltennamen in MSSQL suchen

by Maik
Categories: SQL
Tags: No Tags
Comments: No Comments
Published on: 04.08.2010

Manchmal passiert es, dass man eine bestimmte Tabellenspalte sucht, aber nicht weiß, in welcher Tabelle diese enthalten ist. Ich hatte das Problem, dass eine Tabelle in einem externen Programm Probleme bereitet hat. Natürlich habe ich keine Chance das Programm zu debuggen, ich habe aber heraus bekommen, dass eine View für den Fehler verantwortlich ist. Das einzige was ich heraus bekam war aber nur der Spaltenname und nicht die Tabelle. Um nicht jede Tabelle einzeln öffnen zu müssen hat mir die folgende SQL weiter geholfen.

SELECT table_name = sysobjects.name,
column_name = syscolumns.name,
datatype = systypes.name,
length = syscolumns.length
FROM sysobjects
JOIN syscolumns ON sysobjects.id = syscolumns.id
JOIN systypes ON syscolumns.xtype=systypes.xtype
WHERE syscolumns.name like 'msrep%' -- natürlich den gesuchten Tabellenspaltennamen
ORDER BY sysobjects.name,syscolumns.colid

Unable to return ‘affix’ for unknown CreoleType

by Maik
Categories: Allgemein
Tags: No Tags
Comments: No Comments
Published on: 04.05.2010

Symfony 1.0 auf PHP 5.3 upzugraden ist eigentlich nicht problematisch.Man braucht nur die aktuellste Version 1.0.22.
Wenn man dann ein “propel-build-model” macht, kommt die Fehlermeldung:

Unable to return 'affix' for unknown CreoleType

Dann muss man noch in der Datei /lib/symfony/vendor/creole/CreoleTypes.php in der Zeile 39 die Konstante TEXT mit dem Wert 30 belegen. Ursprünglich ist diese mit dem Wert 17 belegt, was aber gleichzeitig auch der Wert für den LONGVARCHAR Wert ist.

const TEXT = 17
// wird zu
const TEXT = 30 // debug wegen PHP 5.3

Es ist mehr ein Hack als eine wirkliche Problemlösung aber es ist nicht damit zu rechnen, dass dieser Teil von Creole im Symfony 1.0 noch debuggt wird. Schließlich ist der Support für Symfony 1.0 ausgelaufen.

Meine persönliche Meinung ist, dass es ein tolles System ist, aber das Upgrade auf 1.1 war bei unserem großen System nicht ohne großes Redesign möglich. Jetzt auf die 1.4 umzusteigen wäre auch fast sinnlos, da wiederum ein Upgrade auf das kommende Symfony 2.0 einen weiteren Bruch bedeuten würde. Ich hoffe inständig dass Sensio jetzt endlich mal die API gleich lässt, wenn Symfony wirklich im Enterprise Umfeld erfolgreich werden soll.

max-width Problem im Internet Explorer 6 (IE6)

by Maik
Categories: Allgemein
Tags: No Tags
Comments: No Comments
Published on: 12.11.2009

unter http://www.bestviewed.de/css/bsp/maxwidth findet man eine sehr elegante Möglichkeit um dem Problem max-width im IE bei zu kommen. Man muss einfach eine Tabelle als Conditional Comment nur für den IE anlegen. Denn:

Der IE ignoriert die Breitenangabe einer Tabellenzelle solange diese größer ist, als die im Fenster zur Verfügung stehende Breite. (Zitat s.o.)

Um also eine Element zu erhalten, welches maximal 30em breit ist, wenn weniger Inhalt ist aber schmaler sein soll, muss man nur folgenden Code verwenden.

Hier kann jetzt ganz viel Text stehen.

komm doch mal wieder vorbei oder die Google craw rate

by Maik
Categories: Allgemein, Suchmaschinen
Tags: No Tags
Comments: No Comments
Published on: 04.11.2009

Ich habe gerade einen interessanten Artikel auf www.sitepoint.com gelesen.

http://www.sitepoint.com/forums/showthread?t=643978

Es geht um die “crawl” Rate vom googlebot. Das ist die Häfigkeit mit der der Googlebot bei einer Internetseite “reinschaut”, sprich nach geändertem und neuem Inhalt sucht. Ich habe diesen 10-Punkte-Plan mal kurz übersetzt, da ich denke, dass es wichtig ist diese Punkte im Hinterkopf zu behalten.

  1. aktualisiere den Inhalt regelmäßig und oft
  2. stell sicher, dass der Server korrekt läuft und sicher konfiguriert ist
  3. behalte die Ladezeit der Seite im Auge (vor allem die, die der Browser braucht um alles vollständig zu laden. Firebug ist dein Freund)
  4. kontrollier die interne Link Struktur der Seite (Google mag es nicht über 2 verschiedene Links zu einer Seite zu kommen)
  5. versuch mehr “Backlinks” von regelmäßig aktualisierten Seiten zu bekommen
  6. Stell die “crawl” Geschwindigkeit bei dein Google Webmaster Tools ein
  7. füge eine Sitemap hinzu (wenn man diese per XML zur Verfügung stellt, kann Google diese auch direkt abrufen.)
  8. stelle sicher, dass der Server den korrekten Header zurück gibt.
  9. alle Seiten sollten eindeutige Titel und Meta-Tags haben
  10. beobachte Google crawl in den Google Webmaster Tools und schau was geht und was nicht

Ich persönlich möchte noch anmerken, dass bei der Seitenoptimierung der Title Tag von Google & Co.  auch gewertet und gewichtet wird. Dass ein ALT Tag eines Bildes gefüllt sein sollte versteht sich von selbst.

Putty mit SSH PublicKey Verfahren

by Maik
Categories: Allgemein
Tags: No Tags
Comments: 1 Comment
Published on: 11.10.2009

Über 80% aller Webserver laufen mit einem Unix Derivat, meist Linux. Um auf solche Maschinen zugreifen zu können benötigt man einen Shell/Bash Zugriff. Das geht recht einfach mit einem SSH.

Um z.B. auf einem Ubuntu System SSH einzurichten ist sehr gut auf der Wiki Seite von ubuntuusers.de beschreiben. http://wiki.ubuntuusers.de/SSH

Das Problem daran ist, dass der Zugang für alle offen ist, d.h. es kann jeder versuchen sich auf diesem Server ein zu loggen. Natürlich verwenden wir sichere Passwörter, aber dennoch wäre es doch schöner, wenn man den Zugriff für alle anderen, außer einem selbst und ggf. Mitentwickler, sperren könnte. Das geht und zwar relativ einfach, man muss nur einen SSH public/private Key erzeugen und diesen dann verwenden. Alle anderen Zugänge werden gesperrt. Unter http://www.systemengineers.de/linux/debian/key-basierte-ssh-logins-mit-putty ist der Vorgang sehr anschaulich für User beschrieben, die wie ich auf Arbeit ein Windows System mit putty benutzen.

UTF-8 Zeichen in HTML-Entities umwandeln

by Maik
Categories: Allgemein
Tags: No Tags
Comments: 1 Comment
Published on: 07.10.2008

Manchmal muss man einen Fluss durchqueren, um zu sehn, dass es ganz in der Nähe eine Brücke gibt.

Ich habe versucht sämtliche Sonderzeichen die in meiner Firma so verwendet werden rauszufinden, damit ich diese dann gleich in HTML Entities umwandeln kann. Da unser Backend und Frontend ISO-8859-15 codiert ist, ließen sich die UTF-8 Strings nicht direkt in die DB schreiben.

Mit escape kann man die Daten vorm Senden UTF-8 encodieren. (bzw. URL encodieren). Im PHP nimmt man dies dann wieder entgegen mit rawurldecode(). Dann wird der Text durch folgende Funktion gejagt:

$suchmuster = '/(%u)(\w{4})/';
$ersetzung = '&#x$2;';
$inhalt = preg_replace($suchmuster, $ersetzung, $inhalt);

Die Ersetzen-Funktion sucht nach “%u” und den darauf folgenden 4 Buchstaben/Zahlen. Ersetzt wird das %u mit “&#x“, was die Codierung für hexadezimale HTML-Entities ist, und dann werden die 4 Buchstaben/Zahlen also der Hexcode eingefügt. Abschließend noch ein Semikolon zum Schluss und fertig ist der UTF-8 Konverter.

Wichtig zu erwähnen wäre, dass “normale” Umlaute, die sozusagen vom Zeichensatz unterstützt werden z.B. (ä,ö,ü) extra umgewandelt werden müssen. Bevor die Frage “Wozu das Ganze?” auftaucht, in unserem Eingabefeld sind teilweise HTML-Entities und teilweise richtige Sonderzeichen. Wenn ich nun  htmlentities() laufen lasse, wandelt er mir alles um auch bereits umgewandelte Zeichen wie ä.

SQL Server 2005 Verbindungsfehler

by Maik
Categories: SQL
Tags: No Tags
Comments: No Comments
Published on: 07.08.2008

Wer die folgende Fehlermeldung, bei einer Verbindung zu einem MS SQL 2005 Server bekommt, tut mir ehrlich gesagt leid.

Microsoft SQL Server-Anmeldung

Fehler bei der Verbindung: SQLState: ’01000′ SQL Server-Fehler: 11001 [Microsoft][ODBC SQL Server Driver][DBNETLIB]ConnectionOpen (Connect()). Fehler bei der Verbindung: SQLState: ’08001′ SQL Server-Fehler: 6 [Microsoft][ODBC SQL Server Driver][DBNETLIB]Der angegebene SQL Server konnte nicht gefunden werden.

Ich habe fast einen Tag lang nach einer Lösung gesucht und sie durch einen Kollegen, nicht aber durchs Internet, gefunden.

Es gibt einenKnowledgebase Arktikel auf den immer verwiesen wird, in dem vieles steht, nicht jedoch der Fehler, der es bei mir war.

MS-KB: 328306

Bei mir war es ein “Sicherheitsfeature” von Windows Vista. Der Dienst COM+Systemanwendung steht nicht auf “automatisch starten”, sondern ist auf “manuell” eingestellt. Nachdem ich diesen Dienst gestartet hatte, konnte ich unsere CRM-Anwendung starten und die MSSQL Management Konsole hatte auch Zugriff auf den Server.

MySQL Sichten(Views) und Prozeduren (Procedures)

by Maik
Categories: SQL
Tags: No Tags
Comments: 1 Comment
Published on: 25.03.2008

Bevor ich bei meiner jetzigen Firma angestellt war, habe ich mir eingebildet etwas über SQL (MySQL) zu wissen. Dann habe ich jedoch den Microsoft-SQL-Server kennen gelernt. Ich bin generell kein Microsoft Fan, der SQL-Server ist aber schon ein sehr leistungsfähiger Server. Durch die bereits vorhandenen Strukturen musste ich mich erst einmal durchfitzen unter anderem auch durch Sichten und Prozeduren. Aus heutiger Sicht weiß ich nicht, wie ich ohne diese SQL Werkzeuge auskommen konnte.

Kommen wir als erstes zu den Sichten (Views):

Um den Sinn einer Sicht zu verstehen, versuche ich es einmal mit einem Beispiel. (dies ist ein MySQL-Code in anderen SQL-Sprachen weicht dieser aber nicht allzu sehr ab)

CREATE VIEW terms AS
select term.term_id, name, slug, term_group,
taxonomy, description, parent, count
from wp_terms as term
INNER JOIN wp_term_taxonomy as tax
ON term.term_id = tax.term_id

Mit

CREATE VIEW * AS

wird eine Sicht eingeleitet. Ich habe hier mal als Beispiel die WordPress Datenbank genommen um einen JOIN über die Tabellen wp_term_taxonomy und wp_terms zu erstellen. Die Frage die ich mir am Anfang gestellt habe war: “Wozu soll ich das so umständlich machen?”. Man kann die SQL ja auch direkt in den PHP-Quellcode schreiben. Das mag zwar fürs erste stimmen, wenn man das Ganze aber etwas weiter spinnt, wird es vielleicht deutlicher. In WordPress ist es prinzipiell möglich den Tabellenpräfix zu ändern. Wenn ich das im Nachhinein ändere, wird das in der WordPress-Programmierung automatisch erledigt, nehmen wir jetzt aber weiter an, dass ich mir ein Plugin oder eine eigene Seite mit SQL-Abfragen geschrieben habe. Ich müsste jetzt manuell durch alle Abfragen durchgehen und die Tabellen umbenennen. Wenn ich aber Sichten einsetzte muss ich dies nur einmalig zentral ändern und alle Scripte die auf die Sicht zugreifen funktionieren weiterhin. Sichten helfen Redundanz zu vermeiden. Ich muss den SQL-Code nicht mehrmals hinterlegen, sondern kann ihn an einer Stelle ändern. Für Webmaster, die sich bis jetzt nur mit “kleinen” Seiten auseinander gesetzt haben, ist der Sinn vielleicht nicht offensichtlich, wenn man jedoch eine Webanwendung mit dutzenden von Tabellen hat, lernt man Views sehr schnell zu schätzen.

Als zweites möchte ich Prozeduren vorstellen.

Eine Prozedur ist ein universelle Werkzeug in der täglichen Arbeit mit SQL. Eine Prozedur ermöglicht es viele SQL-Anweisungen in einer Anweisung zusammen zu fassen. Nehmen wir an, dass ich den Umsatz pro Kunde und Monat ermitteln will. Das geht sicherlich recht einfach mit einigen JOINS und einer GROUP BY Klausel. Jedoch müsste ich diese Werte bei jeder Abfrage erneut generieren. Bei 10.000 Kunden mag das vielleicht noch gehen. Bei 1.000.00 Kunden wird es schon recht aufwendig für den SQL-Server. Die Last ist auf jeden Fall enorm hoch. Am einfachsten wäre es doch, diese Zahlen einmal in der Woche (oder täglich) in eine gesonderte Tabelle weg zu schreiben. Genau dass kann man mit Hilfe einer Prozedur und eines Cronjobs machen.

DELIMITER $$
DROP PROCEDURE IF EXISTS `proc_umsatz_monatlich`$$
CREATE PROCEDURE `proc_umsatz_monatlich` ()
BEGIN
INSERT INTO umsatz_monatlich
SELECT kunde_id, umsatz
FROM rechnungen
GROUP BY YEAR(datum), MONTH(datum), kunde_id
END$$
DELIMITER ;

Der Vorteil von Prozeduren liegt auf der Hand. Man kann sie mit Variablen füttern und somit das Ergebnis beeinflussen (In einer Prozedur kann man z.B. auch IF Abfragen verwenden). Die Prozedur selbst kann beliebig verwandelt und an neue Gegebenheiten angepasst werden, ohne dass sämtlicher SQL-Code umgeschrieben werden muss. Das hat vor allem Vorteile für z.B. die Suche einer Seite. Diese wir normalerweise mit wenigen Parametern angesprochen (Suchbegriff und ggf. Einschränkungen wie Zeitraum o.ä.) und gibt als Ergebnis eine Tabelle zurück. Ich musste in unsere Suche eine Tabelle zusätzlich einbinden. Das ging ohne eine Zeile im PHP-Quellcode zu verändern, nur indem ich die Prozedur verändert habe. Es gibt Programmierer, vor allem in der professionellen Programmierung, die der Meinung sind, dass ein Client (das Clientprogramm) keinen direkten Zugriff auf die Datenbank haben darf. Das ist ein recht radikaler Ansatz, dem ich mich nicht anschließen möchte. Sinnvoll wäre es aber z.B. dass man dem Client, im Falle der Webprogrammierung dürfte das zumeist “www-data” sein, nur SELECT oder UPDATE Befehle erlaubt. DROP und DELETE sind nur Prozeduren vorbehalten. Das würde dem Schutz vor SQL-Injection einigen Vorschub leisten. Wenn man sogar soweit geht, die Einschränkung auf UPDATE Befehle auszuweiten, wäre das ein großer Sicherheitsgewinn.
Eine weitere wichtige Funktion von Prozeduren soll das nachfolgende Beispiel verdeutlichen:

CREATE PROCEDURE curdemo()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE a CHAR(16);
DECLARE b,c INT;
DECLARE cur CURSOR FOR SELECT id,data FROM test.t1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur1;
REPEAT
FETCH cur1 INTO a, b;
IF NOT done THEN
IF b < c THEN
INSERT INTO test.t3 VALUES (a,b);
ELSE
INSERT INTO test.t3 VALUES (a,c);
END IF;
END IF;
UNTIL done END REPEAT;
CLOSE cur;
END

Man kann in einer Prozedur durch ein Ergebnis einer SQL, Zeile für Zeile durchgehen und die Datenwerte für Bedingungen, INSERT, DELETE oder UPDATE Befehle nutzen. Man kann einen CURSOR ähnlich einer while Schleife benutzen. Das zu den Vorteilen. Der Entscheidende Nachteil ist, die Geschwindigkeit. Wenn ich ein UPDATE Befehle ausführe, selbst wenn es zehntausende Zeilen betrifft, ist der Server in meist weniger als einer Sekunde fertig (Abhängig von der Tabelle, dem Index und weiterer Faktoren). Mit einer CURSOR Operation kann ich prinzipiell die gleiche Funktion ausführen, wie mit dem UPDATE Befehl, diese würde jedoch erheblich länger Dauern. Deshalb ein Wort der Warnung. CURSOR Operationen nur mit Bedacht einsetzen und alle Alternativen vorher ausschöpfen. Als bewährtes Mittel um diesen SQL Befehl zu vermeiden, haben sich für mich temporäre Tabellen erwiesen. Man kann das Ergebnis einer SELECT Anweisung in eine Tabelle speichern und diese dann für weiter gehende Aktionen benutzen.
Dazu fällt mir wieder meine Suche ein. Als erstes erstelle ich eine Temporäre Tabelle mit bestimmten IDs die ich aus den Einschränkungen Zeitraum bzw. Thema gewinne. Diese IDs benutze ich dann als Grundlage für die weitere Recherche nach dem Suchwort. Anfänglich hat die Ausführung ca. 30 Sekunden gedauert.

Das ist auch noch ein wichtiger Punkt, den ich ansprechen möchte, obwohl es die meisten Programmierer wissen sollten. Man sollte erst seinen Code schreiben, so dass er einfach zu warten ist und den Anforderungen entspricht. Erst dann sollte man sich auf den Weg von Flaschenhälsen machen, sprich optimieren. Ein gutes Beispiel ist eine Webseite, die mehrere Zehntausend Zugriffe pro Stunde hat. Wenn man diese versucht von Anfang an zu optimieren ohne eine entsprechende Serverlast zum Testen zu haben, ist das bestenfalls verschwendete Zeit, schlimmsten Falls hat man sich auf eine falsche Annahme verlassen und die Optimierung kostet mehr Ausführungszeit als der eigentlich Code.

Zurück zur SQL. Durch schrittweises optimieren, z.B. einen zusätzlichen Index auf die durchsuchten Tabellen und dem Einsatz von temporären Tabellen konnte ich die Ausführung auf, je nach Aufruf, 0.7 – 1.5 Sekunden herunterschrauben. Die Suche geht dabei über 14 Tabellen, von denen 7 durchsucht und 7 für die Ausgabe (z.B. Bilder, Titel, Sortierung etc.) ausgewertet werden.

«page 2 of 3»

Welcome , today is Sonntag, 05.02.2012