Wypowiedzi
-
Na moje to coś takiego będzie: http://di.wsb.poznan.pl:100/gl/3485321.png
Nie działa z portem 100 wklejanie obrazków z zewnątrz.Ten post został edytowany przez Autora dnia 22.06.14 o godzinie 23:25 -
No i teraz są konkrety :)
Jak dla mnie wyliczanie i prezentowanie danych pobranych z bazy danych to nie program typu kalkulator tylko zwykły raport prezentujący dane który wcześniej wypytał użytkownika o parę informacji na start.
Robię sobie taki pracujący na serwerze web wykonany w dowolnym języku o jakim pisze przedmówca a następnie zainteresowanym przesyłam tylko link. -
Może napisz w kilku zdaniach o co chodzi a nie wszystko w jednym a po kropce kontynuacja zdania.
Poruszasz kilka tematów i wypowiedź ciężko zrozumieć.
Napisz wymagania, wymień funkcje jakie są potrzebne.
Ja z wypowiedzi zrozumiałem, że masz dane w bazie zabezpieczone hasłem. Hasło i być może użytkownik się zmienia w jakimś okresie czasu. Dodatkowo chcesz zrobić aplikację ("Kalkulator") która łączy się z bazą, pobiera dane i coś z nimi robi.
Temat który cię nurtuje: Jak utajnić użytkownika i hasło do bazy aby użytkownik aplikacji go nie poznał.
Wnioskuję, że chodzi o bezpieczeństwo danych.
Tak jak pisał przedmówca na pewno połączenie pomiędzy aplikacją a bazą danych musi być szyfrowane aby zapewnić bezpieczeństwo przekazywania danych.
Jeżeli chodzi o ciągle zmieniające się hasło/użytkownika bazy danych i jego utajnienie dla użytkownika programu zrobiłbym tak:
1. Tworzę sobie wzór np. u:mojTajnyUzytkownik;h:MojeTajneHasło1234
2. Wymyślam sobie znany tylko mi algorytm szyfrujący i szyfruję taką informację. Zaszyfrowaną informację upubliczniam w znanym sobie miejscu w sieci
3. W programie który ma uzyskać dostęp do danych zaszywam algorytm deszyfrujący wiadomość. W momencie włączania programu ten pobiera sobie z sieci inforamcję z pkt 1 i 2 a następnie deszyfruje. Danych odszyfrowanych używam do autentykacji w bazie.
Taki motyw z kluczem prywatnym i publicznym. Zamiast wymyślać sobie metody możesz użyć PGP do szyfrowania i odczytywania wiadomości. Masz pewność, że tylko twoja aplikacja odczyta wiadomość z użytkownikiem i hasłem.
Jedyne o czym trzeba pamiętać to o stworzeniu wiadomości i jej upublicznieniu w odpowiednim miejscu w sieci w momencie zmiany nazwy użytkownika/hasła dostępu do bazy danych. -
Aniu... Żaden twój opis nie oddaje treści problemu jaki masz do rozwiązania. Podrzuć może definicje obu tabel. Dodaj nam jakieś przykładowe dane. Powiedz jakie są klucze główne i obce (jeżeli są) tabel.
Jeżeli jest to zadanie akademickie i wykładowca oczekuje od ciebie wyniku postaci:
imie, nazwisko, dana1, dana2, dana3
Jan, Kowalski, cos tam 1, cos tam 2, cos tam 3
NULL, NULL, cos tam 4, cos tam 5, cos tam 6
i określa, że drugi wiersz to dane kowalskiego to chyba powinni takiego zwolnić z nauczania bo nie wie czego oczekuje od swoich studentów.
Przecież brak informacji w kolumnach imie, nazwisko to też informacja. Mówi ona nam, że mamy zestaw danych (cos tam 4, cos tam 5, cos tam 6) ale nie wiemy jakiej osoby one dotyczą. To, że są posortowane w taki sposób wcale nie oznacza, że dotycza osoby w wiersza poprzedzającego lub następującego.
Z twojego przykładu wynika, że "dana 12" dotyczy "imie 4". Posortuj wynik zapytania odwrotnie i wyjdzie ci, że "dana 12" dotyczy "imie 5" co nie jest prawdą. Wniosek z tego taki, że w każdym wierszu wymaga się aby było podane imię oraz nazwisko aby wiedzieć kogo dane dotyczą. -
Ciekawa konstrukcja typu
select * from tab1 where (x, y) in (select x, y from tab2)
przyznaję, że nie znałem. Ale człowiek uczy się przecież przez całe życie.
Z ciekawości zrobiłem sobie analyze tego zapytania i porównałem z zapytaniem z "join". Planer w PostgreSQL wykonuje to prawie identycznie. Zapytanie z "join" jest jednak bardziej optymalne przy stosunku wierszy tab1 > tab2, ponieważ skanowana jest najpierw tabela o mniejszej ilości rekordów i do niej wyszukiwane są odpowiedniki tabeli o większej ilości rekordów.
Przy zapytaniu "where (x, y) in" zawsze najpierw skanowana jest tabela tab1 a dopiero potem szukane są odpowiedniki.
Taka moja obserwacja na PostgreSQL... -
Jeżeli mowa o prostych zapytaniach SQL... Testowane na PostgreSQL 9.2 czyli składnia dla Oracle czy mySQL może się nieco różnić.
Zakładam taki przypadek testowy na podstawie tego, co przeczytałemcreate table if not exists tab1(
Chcę pobrać dane z tab1 na podstawie danych w tabeli tab2 (dwie kolumny mają tożsame wartości) czyli wyciągam dane, gdzie atrybut x oraz y w obu tabelach jest równy:
x int,
y int,
dana1 text,
dana2 text
);
create table if not exists tab2(
x int,
y int,
cos_tam text
);
insert into tab1 values (1,1,'a','b');
insert into tab1 values (1,2,'c','d');
insert into tab1 values (1,3,'e','f');
insert into tab1 values (2,1,'g','h');
insert into tab1 values (2,2,'i','j');
insert into tab2 values (1,2,'test1');
insert into tab2 values (2,1,'test2');select tab1.* from tab1 join tab2 on tab1.x = tab2.x AND tab1.y = tab2.y;
Chcę zaktualizować wybraną kolumnę wszystkim krotkom tabeli tab1 których wartości atrybutów x oraz y są tożsame z odpowiednimi wartościami tab2:update tab1 t1 set dana2 = 'y' from tab2 t2 where t1.x = t2.x and t1.y = t2.y;
Na koniec chcę usunąć dane z tab1 które występują w tab2:delete from tab1 t1 using tab2 t2 where t1.x = t2.x and t1.y = t2.y;
Nie napisałeś co można w tym programie a co nie. W treści jest tylko "coś tam, coś tam ... where ...". Kompletnie nie rozumiem dlaczego wszyscy założyli, że możesz tylko zmieniać klauzulę "where". Zakładam, że w programie o którym mowa, można wpisać po prostu treść zapytania jakie ma zostać wykonane i przejrzeć wyniki. Jeżeli moje założenie jest trafne to myślę, że temat jest wyczerpany :) -
Wyznaję zasadę, że jak coś da się zrobić za pomocą engine danej bazy danych to robi się za pomocą bazy danych. Tutaj się da :)
Mariusz P.:
Spróbuj:
while ($tab=$odp->fetch()){
$firmyId[] = $tab['firmy_id'];
}
$sql="UPDATE firmy SET data_cron=now() WHERE firmy_id in (".implode(',',$firmyId).")";
$db->query($sql);
Już proponowałem rozwiązanie z wrzuceniem danych do ramu... dostałem odpowiedź "nie chcę".
Ostatnia moja wypowiedź bo temat jest wyczerpany.
Eh. Mieć ciastko i zjeść ciastko. -
Sorka ale dałeś LIMIT 500 to zakładałem, ze tylko tyle rekordów i to w dodatku najstarszych bo jeszcze dałeś ORDER BY. To co tak na prawdę chcesz zrobić?
Nie musisz przecież ładować do ramu. Możesz przecież pracować na wyniku zapytana. A co do pamięci to z typem bigint to jakieś 25MB bo to jedna kolumna. Kłócił się jednak nie będę.
Jak potrafisz opisać rekordy zapytaniem SQL to ogóle na nich nie pracuj tylko przekaż dane do polecenia UPDATE. Możesz przecież sobie tak zrobićUPDATE firmy SET data_cron = now() WHERE firmy_id in (SELECT id FROM ....)
Nie wybieraj danych z tabeli którą chcesz aktualizować. Umiesz je opisać to zrób tak jak pisałem.
A z twoim konkretnym przykłademUPDATE firmy SET data_cron = now() ORDER BY data_cron LIMIT 500
i po sprawie -
Zacząłem się rozpisywać ale od Zend'a specem nie jestem. Czepię się tylko tego nieszczęsnego update milion razy robionego w loop'ie.
Zamiast wykonywać X razy UPDATE możesz to zrobić jednym zapytaniem SQL. Zakładając, że "firmy_id" jest typem liczbowym możesz zrobić://Wyciągam id firm do aktualizacji z bazy
$sql = "SELECT firmy_id FROM firmy ORDER BY data_cron LIMIT 500";
$result = $db->fatchAll($sql);
// Przygotowuję liczby po przecinku. Pomijam sobie apostrofy bo dane nie pochodzą z interface użytkownika
$sql = "";
foreach ($rows as $row) {
$sql .= $row['firmy_id'].",";
}
// Ucinam ostatni znak bo to przecinek, który da błąd przy wykonywaniu SQL
$sql = substr($sql, 0, -1);
// Wykonuje jedną aktualizację tabeli podając w WHERE listę firm
$db->getConnection()->exec("UPDATE firmy SET data_cron=now() WHERE firmy_id IN ($sql)");
Metody z Zend'a mogą być trefne bo nie znam Zend'a -
Myślę, że najprościej będzie zrobić
RETURN QUERY SELECT col_status, col_date_detection;
zaraz po ostatnim END IF. Ja akurat lubię jak jest RETURN jeżeli funkcja coś zwraca :)
Tak jak masz dobrze jest. Użycie funkcji w zapytaniu
select funckcja();
jeżeli funkcja zwraca table to raczej jej wywołanie powinno nastąpić po klauzuli FROM. Użycie jej jako atrybutu w tym momencie spowoduje zagregowanie kolumn tabeli do jednej kolumny typu RECORD. Funkcja zwróci oczekiwane kolumny jeżeli użyje się jej tak jakbyśmy odnosili się do tabeli
SELECT * FROM funkcja();
Ten post został edytowany przez Autora dnia 13.05.14 o godzinie 00:14 -
Wszystko napisałeś dobrze. Twój panel ma jednak rozmiar 0px x 0px więc nie zobaczysz go w głównym oknie. Dodaj
PanelKierowcyDodaj panel = new PanelKierowcyDodaj();
Wygląda na to, że ten panel ma się w ten sposób zachowywać zawsze. Te ustawienia dodałbym do konstruktora klasy PanelKierowcyDodaj
panel.setSize(400, 300);
add(panel);
panel.setVIsible(true);public class PanelKierowcyDodaj extends javax.swing.JPanel {
wtedy w kodzie wywołać panel możesz następująco
public PanelKierowcyDodaj() {
initComponents();
setSize(400, 300);
setVisible(true);
}add(new PanelKierowcyDodaj());
Dodatkowo aby sprawdzić czy panel się ogóle wyświetla z reguły robię sobie ramkępanel.setBorder(new MatteBorder(2, 2, 2, 2, Color.BLACK));
albo zmieniam kolor tła. -
Ludzie dzielą się zasadniczo na dwie grupy.
1. Ci, którzy robią backup'y
2. Ci, którzy backup'y robić zaczną
Jestem pewien, że teraz przeskoczysz z drugich do pierwszych :) -
Podałeś zbyt mało szczegółów.
Jaki jest ogóle cel przedsięwzięcia? Chcesz utrzymywać jedną bazę + skalowanie?
Mogę tylko wnioskować, że chcesz ujednolicić dane składowane w obu bazach.
Najlepszym rozwiązaniem było by przeniesienie danych z jednej bazy do drugiej a następnie użycie jednego ze sposobów replikacji. Wszystko zależy od tego co masz oraz co chcesz osiągnąć. -
Szymon G.:
Raczej nie. Zgodnie z UODO samo przechowywanie jest przetwarzaniem, a zatem nie można "przechowywać danych bez zgody na przetwarzanie" oczywiście poza danymi ogólnie dostępnymi, co ładnie komplikuje zabawę :)
Prawda. Z uwagi na osobę zadającą pytanie nie chciałem sypać konkretami + wyciągami i cytatami z ustaw. Z drugiej strony sam szczegółów nie znam bo mam w firmie mądrą od tego głowę która rozwiewa moje wszystkie wątpliwości. -
Pytanie trochę na skróty...
Pierwsza rzecz to taka, że nie "właściciel bazy danych" a administrator danych osobowych.
Druga rzecz to, że nie "właściciel ze zgodą na wysyłanie" tylko osobom z bazy danych, które wyraziły zgodę na wysłanie
A teraz do rzeczy...
Administrator danych osobowych to osoba (niekoniecznie informatyk), która odpowiada na zarządzanie danymi osobowymi.
Jeżeli chcesz wykonać cokolwiek przy pomocy danych osobowych (np. wysłać materiały reklamowe) to musisz dane poddać przetwarzaniu.
Dane osobowe zostały nagromadzone w konkretnych celach. W momencie pobierania porcji danych osobowych od osoby należy poinformować osobę w jakim zakresie pobrane dane będą przetwarzane (uzyskanie zgody na np. wysłanie materiałów reklamowych). Jeżeli osoba która powierza swoje dane osobowe nie została poinformowana o danym przetwarzaniu (np. zrobienie udział w konkursie) wówczas dane nie mogą zostać wykorzystane do przetwarzania.
Plik coockie z reguły przechowuje informację na temat sesji aplikacji web, jakieś ustawienia itp. Dane osobowe wyświetla się w content strony web a nie zapisuje w plikach na lokalnym komputerze użytkownika!
Jeżeli chcesz mimo wszystko tak zrobić musisz zebrać pozwolenia na wykorzystywanie danych osobowych w plikach coockie od użytkowników potencjalnie narażonych na taką czynność. -
Krzysztof N.:
1. Jeśli kolumna / pole`idserialu` varchar(255) COLLATE utf8_unicode_ci NOT NULL
jest kluczem obcym, to zmień jej typ taki jak posiada klucz główny, tj. nabigint(20) unsigned
Tylko, że tam celowo zrobione varchar bo programista nie znając zagadnień bazy danych rozwiązuje problem tym czym umie się posługiwać (jakimś językiem programowania) i wymyślił sobie, że rozdzieli dane jakimś znakiem (w tym wypadku |) i w kodzie aplikacji to odpowiednio obsłuży.
To bardzo częsta sytuacja bo jest masa automatów zakładających obiekty w bazach danych które ogłupiają programistę (albo może raczej myślą za niego). Najczęściej zdarza się przy tworzeniu aplikacji działających po web'ie.
Ostatnio dostałem schemat bazy gdzie programista java miał temat z kluczem głównym założonym na dwóch kolumnach. No to w nowej tabeli stworzył kolumnę typu text a następnie wstadził do niej wartość z dwóch kolumn z klucza rozdzieloną "_" i ciachanie tekstu zaszył w kodzie.
Jaka wielka szkoda, że na naszym rynku stanowisko DBA jest nadal mało doceniane ;( -
Zakładam sobie, że w jednej kolumnie (atrybucie) oraz jednym wierszu (krotce) przechowuję tylko jedną informację.
Kolega tutaj usiłuje w kolumnie "idserialu" przechować X informacji co przeczy założeniu.
Wykonuję drobną modyfikację tabeli oraz zakładam tabelę w której będę przechowywał X informacji z kolumny "idserialu":CREATE TABLE IF NOT EXISTS `cms_newsy` (
Teraz dodaję troszkę danych testowych:
`bf_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`tytul` varchar(85) COLLATE utf8_unicode_ci DEFAULT NULL,
`datadodania` datetime NOT NULL,
UNIQUE KEY `id` (`bf_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `cms_filmy` (
`bf_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`tytul` varchar(250) COLLATE utf8_unicode_ci DEFAULT NULL,
UNIQUE KEY `id` (`bf_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `cms_filmy_newsy` (
`film_id` bigint(20) NOT NULL,
`news_id` bigint(20) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;INSERT INTO cms_filmy(tytul) VALUES ('Kubuś puchatek');
I teraz z kolegi podpunktów:
INSERT INTO cms_filmy(tytul) VALUES ('Smerfy');
INSERT INTO cms_filmy(tytul) VALUES ('Muminki');
INSERT INTO cms_filmy(tytul) VALUES ('Gumisie');
INSERT INTO cms_newsy(tytul, datadodania) VALUES ('Lista najlepszych tytułów ostatniego kwartału' ,'2014-01-10');
INSERT INTO cms_newsy(tytul, datadodania) VALUES ('Czy muminek się wreszcie ożeni?' ,'2013-12-15');
INSERT INTO cms_newsy(tytul, datadodania) VALUES ('Smerfy we Francji...' ,'2013-09-10');
INSERT INTO cms_newsy(tytul, datadodania) VALUES ('Modernizacja newsa' ,'2014-01-01');
INSERT INTO cms_filmy_newsy VALUES (1, 1);
INSERT INTO cms_filmy_newsy VALUES (3, 1);
INSERT INTO cms_filmy_newsy VALUES (4, 1);
INSERT INTO cms_filmy_newsy VALUES (2, 3);
INSERT INTO cms_filmy_newsy VALUES (3, 2);
INSERT INTO cms_filmy_newsy VALUES (1, 4);
INSERT INTO cms_filmy_newsy VALUES (2, 4);
INSERT INTO cms_filmy_newsy VALUES (3, 4);
INSERT INTO cms_filmy_newsy VALUES (4, 4);
a)-- Suma newsow ogole
b)
SELECT
f.tytul, count(fn.film_id) AS liczba_newsow
FROM
cms_filmy f
LEFT JOIN
cms_filmy_newsy fn ON f.bf_id = fn.film_id
GROUP BY
f.tytul
ORDER BY
liczba_newsow desc, tytul;-- Suma newsow z ostatnich 3 miesiecy
c) Jeden news dla paru filmów oznacza również w drugą stronę, że jeden film może posiadać wiele newsów. Jest to model relacji wiele do wielu obsłużony za pomocą tabeli "cms_filmy_newsy" .
SELECT
f.tytul, count(fn.film_id) AS liczba_newsow
FROM
cms_filmy f
LEFT JOIN
cms_filmy_newsy fn ON f.bf_id = fn.film_id
JOIN
cms_newsy n ON n.bf_id = fn.news_id
WHERE
n.datadodania >= (now() - interval 3 month)
GROUP BY
f.tytul
ORDER BY
liczba_newsow desc, tytul;
d) Bonus-- Lista newsow nie starsza niz 3 mies
SELECT
f.*, n.tytul as tytul_newsa, n.datadodania as data_newsa
FROM
cms_filmy f
LEFT JOIN
cms_filmy_newsy fn ON f.bf_id = fn.film_id
JOIN
cms_newsy n ON n.bf_id = fn.news_id
WHERE
n.datadodania >= (now() - interval 3 month);
W mySQL namiętnie nie tworzę. W moim ulubionym PostgreSQL miałbym porobione FOREIGN KEY do tabel z opcją on delete cascade bo wtedy tabela cms_filmy_news byla by automatycznie czyszczona w momencie usuniecia filmu lub newsa. Dorobilbym jeszcze primary key na cms_filmy_newsy albo unique na kolumnach film_id i news_id aby uniknac podwojnych wpisow (przypozadkowan artykulu do filmy. -
Link do strony mógłby podać...
-
Nie dziw się, że nie dostajesz satysfakcjonującej odpowiedzi. Nie zdefiniowałaś dokładnie jakie masz tabele i jakie dane chcesz wyciągnąć. Tutaj najlepszy byłby konkretny przykład. Z wątku wywnioskowałem, ze masz dwie tabele z rokiem, miesiącem oraz jakąś wartością. Nie ma jednak informacji czy wiersze w tabelach się powtarzają tzn. czy w jednej tabeli występuje przypadek dwóch różnych wartości dla tego samego miesiąca i roku. Nie ma również informacji, czy te dane powtarzają się pomiędzy tabelami. Tu z przykładów wnioskuję, że tak.
Proponuję pracować na przykładzie testowym:DROP TABLE IF EXISTS dane_1;
Oraz następujące dane:
CREATE TABLE dane_1
(
rok INT,
miesiac INT,
wartosc INT,
CONSTRAINT dane_1_pkey PRIMARY KEY (rok, miesiac)
);
DROP TABLE IF EXISTS dane_2;
CREATE TABLE dane_2
(
rok INT,
miesiac INT,
wartosc INT,
CONSTRAINT dane_2_pkey PRIMARY KEY (rok, miesiac)
);INSERT INTO dane_1 VALUES (2012, 10, 100);
INSERT INTO dane_1 VALUES (2012, 11, 80);
INSERT INTO dane_1 VALUES (2012, 12, 10);
INSERT INTO dane_1 VALUES (2013, 10, 25);
INSERT INTO dane_1 VALUES (2013, 11, 40);
INSERT INTO dane_2 VALUES (2012, 10, 200);
INSERT INTO dane_2 VALUES (2012, 11, 50);
INSERT INTO dane_2 VALUES (2012, 12, 20);
INSERT INTO dane_2 VALUES (2013, 10, 5);
INSERT INTO dane_2 VALUES (2013, 11, 45);
Zakładam, że chcesz wyjąć dane z obu tabel a jeżeli dla danego miesiąca oraz roku informacja się powtórzy to chcesz odrzucić tę o niższej wartości z pola "wartość".
Zawsze staraj się operować na danych za pomocą engine bazy danych. Do wtyczek z innymi językami sięgaj dopiero kiedy chcesz zrobić coś czego nie wspiera engine bazy.
Proponuję przeanalizować poniższy kod SQL:WITH
1. Scal obie tabele
result AS
(
SELECT * FROM dane_1 UNION ALL SELECT * FROM dane_2
)
SELECT
rok, miesiac, MAX(wartosc) AS wartosc
FROM
result
GROUP BY
rok, miesiac
ORDER BY rok, miesiac
2. Poszukaj maksymalnej wartości dla danego roku oraz miesiąca i pogrupuj po kolumnach rok, miesiac
3. Posortuj od najstarszego roku i miesiąca -
Aby mieć możliwość przeczytania tego posta musisz być członkiem grupy Programiści